Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 4/4] cpufreq: Use arch specific feedback for cpuinfo_cur_freq
From: Beata Michalska @ 2024-04-05 13:33 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, ionela.voinescu, vanshikonda
  Cc: sudeep.holla, will, catalin.marinas, vincent.guittot, sumitg,
	yang, lihuisong
In-Reply-To: <20240405133319.859813-1-beata.michalska@arm.com>

Some architectures provide a way to determine an average frequency over
a certain period of time based on available performance monitors (AMU on
ARM or APERF/MPERf on x86). With those at hand, enroll arch_freq_get_on_cpu
into cpuinfo_cur_freq policy sysfs attribute handler, which is expected to
represent the current frequency of a given CPU, as obtained by the hardware.
This is the type of feedback that counters do provide.

Signed-off-by: Beata Michalska <beata.michalska@arm.com>
---
 drivers/cpufreq/cpufreq.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 66e10a19d76a..603533b2608f 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -795,8 +795,10 @@ store_one(scaling_max_freq, max);
 static ssize_t show_cpuinfo_cur_freq(struct cpufreq_policy *policy,
 					char *buf)
 {
-	unsigned int cur_freq = __cpufreq_get(policy);
+	unsigned int cur_freq = arch_freq_get_on_cpu(policy->cpu);
 
+	if (!cur_freq)
+		cur_freq = __cpufreq_get(policy);
 	if (cur_freq)
 		return sprintf(buf, "%u\n", cur_freq);
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v3 3/9] drm: xlnx: zynqmp_dpsub: Add connected live layer helper
From: Tomi Valkeinen @ 2024-04-05 12:12 UTC (permalink / raw)
  To: Anatoliy Klymenko
  Cc: dri-devel, linux-arm-kernel, linux-kernel, devicetree,
	linux-media, Laurent Pinchart, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Michal Simek,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Jonas Karlman,
	Jernej Skrabec, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Mauro Carvalho Chehab
In-Reply-To: <20240321-dp-live-fmt-v3-3-d5090d796b7e@amd.com>

On 21/03/2024 22:43, Anatoliy Klymenko wrote:
> Add a helper function capturing the first connected live display layer
> discovery logic.
> 
> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
> ---
>   drivers/gpu/drm/xlnx/zynqmp_dp.c | 37 +++++++++++++++++++++++--------------
>   1 file changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 04b6bcac3b07..4faafdd76798 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1276,28 +1276,40 @@ static void zynqmp_dp_encoder_mode_set_stream(struct zynqmp_dp *dp,
>    * DISP Configuration
>    */
>   
> +/**
> + * zynqmp_dp_disp_connected_live_layer - Return the first connected live layer
> + * @dp: DisplayPort IP core structure
> + *
> + * Return: The first connected live display layer or NULL if none of the live
> + * layer is connected.

"layers"

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

  Tomi


> + */
> +static struct zynqmp_disp_layer *
> +zynqmp_dp_disp_connected_live_layer(struct zynqmp_dp *dp)
> +{
> +	if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO))
> +		return dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_VID];
> +	else if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX))
> +		return dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX];
> +	else
> +		return NULL;
> +}
> +
>   static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
>   				  struct drm_bridge_state *old_bridge_state)
>   {
> -	enum zynqmp_dpsub_layer_id layer_id;
>   	struct zynqmp_disp_layer *layer;
>   	const struct drm_format_info *info;
>   
> -	if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO))
> -		layer_id = ZYNQMP_DPSUB_LAYER_VID;
> -	else if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX))
> -		layer_id = ZYNQMP_DPSUB_LAYER_GFX;
> -	else
> +	layer = zynqmp_dp_disp_connected_live_layer(dp);
> +	if (!layer)
>   		return;
>   
> -	layer = dp->dpsub->layers[layer_id];
> -
>   	/* TODO: Make the format configurable. */
>   	info = drm_format_info(DRM_FORMAT_YUV422);
>   	zynqmp_disp_layer_set_format(layer, info);
>   	zynqmp_disp_layer_enable(layer);
>   
> -	if (layer_id == ZYNQMP_DPSUB_LAYER_GFX)
> +	if (layer == dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX])
>   		zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, true, 255);
>   	else
>   		zynqmp_disp_blend_set_global_alpha(dp->dpsub->disp, false, 0);
> @@ -1310,11 +1322,8 @@ static void zynqmp_dp_disp_disable(struct zynqmp_dp *dp,
>   {
>   	struct zynqmp_disp_layer *layer;
>   
> -	if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO))
> -		layer = dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_VID];
> -	else if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_GFX))
> -		layer = dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX];
> -	else
> +	layer = zynqmp_dp_disp_connected_live_layer(dp);
> +	if (!layer)
>   		return;
>   
>   	zynqmp_disp_disable(dp->dpsub->disp);
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v5 02/10] dt-bindings: mailbox: Add mboxes property for CMDQ secure driver
From: Jason-JH Lin (林睿祥) @ 2024-04-05 14:33 UTC (permalink / raw)
  To: conor@kernel.org
  Cc: linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	Houlong Wei (魏厚龙),
	devicetree@vger.kernel.org, Shawn Sung (宋孝謙),
	CK Hu (胡俊光), conor+dt@kernel.org,
	robh@kernel.org, linux-arm-kernel@lists.infradead.org,
	krzysztof.kozlowski+dt@linaro.org, matthias.bgg@gmail.com,
	jassisinghbrar@gmail.com, angelogioacchino.delregno@collabora.com
In-Reply-To: <20240404-lankiness-devouring-d4d012b22cb9@spud>

On Thu, 2024-04-04 at 15:52 +0100, Conor Dooley wrote:
> On Thu, Apr 04, 2024 at 04:31:06AM +0000, Jason-JH Lin (林睿祥) wrote:
> > Hi Conor,
> > 
> > Thanks for the reviews.
> > 
> > On Wed, 2024-04-03 at 16:46 +0100, Conor Dooley wrote:
> > > On Wed, Apr 03, 2024 at 06:25:54PM +0800, Shawn Sung wrote:
> > > > From: "Jason-JH.Lin" <jason-jh.lin@mediatek.com>
> > > > 
> > > > Add mboxes to define a GCE loopping thread as a secure irq
> > > > handler.
> > > > This property is only required if CMDQ secure driver is
> > > > supported.
> > > > 
> > > > Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
> > > > Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> > > > ---
> > > >  .../bindings/mailbox/mediatek,gce-mailbox.yaml         | 10
> > > > ++++++++++
> > > >  1 file changed, 10 insertions(+)
> > > > 
> > > > diff --git
> > > > a/Documentation/devicetree/bindings/mailbox/mediatek,gce-
> > > > mailbox.yaml
> > > > b/Documentation/devicetree/bindings/mailbox/mediatek,gce-
> > > > mailbox.yaml
> > > > index cef9d76013985..c0d80cc770899 100644
> > > > --- a/Documentation/devicetree/bindings/mailbox/mediatek,gce-
> > > > mailbox.yaml
> > > > +++ b/Documentation/devicetree/bindings/mailbox/mediatek,gce-
> > > > mailbox.yaml
> > > > @@ -49,6 +49,16 @@ properties:
> > > >      items:
> > > >        - const: gce
> > > >  
> > > > +  mediatek,gce-events:
> > > > +    description:
> > > > +      The event id which is mapping to the specific hardware
> > > > event
> > > > signal
> > > > +      to gce. The event id is defined in the gce header
> > > > +      include/dt-bindings/gce/<chip>-gce.h of each chips.
> > > 
> > > Missing any info here about when this should be used, hint - you
> > > have
> > > it
> > > in the commit message.
> > > 
> > > > +    $ref: /schemas/types.yaml#/definitions/uint32-arrayi
> > > 
> > > Why is the ID used by the CMDQ service not fixed for each SoC?
> > > 
> > 
> > I forgot to sync with Shawn about this:
> > https://lore.kernel.org/all/20240124011459.12204-1-jason-
> > jh.lin@mediatek.com
> > 
> > I'll fix it at the next version.
> 
> When I say "fixed" I don't mean "this is wrong, please fix it", I
> mean
> "why is the value not static for a particular SoC". This needs to be
> explained in the patch (and the description for the event here needs
> to
> explain what the gce-mailbox is reserving an event for).
> 
Oh, I see. Thanks for noticing me.

We do want to reserve a static event ID for gce-mailbox to different
SoCs. There are 2 mainly reasons to why we set it in DTS:
1. There are 1024 events IDs for GCE to use to execute instructions in
the specific event happened. These events could be signaled by HW or SW
and their value would be different in different SoC because of HW event
IDs distribution range from 0 to 1023.
If we set a static event ID: 855 for mt8188, it might be conflict the
event ID original set in mt8195.

2. If we defined the event ID in DTS, we might know how many SW or HW
event IDs are used.
If someone wants to use a new event ID for a new feature, they could
find out the used event IDs in DTS easily and avoid the event ID
conflicting.

The reason why we define a event ID is we want to get a SW signal from
secure world. We design a GCE looping thread in gce-mailbox driver to
wait for the GCE execute done event for each cmdq secure packets from
secure world.

Regards,
Jason-JH.Lin

> Thanks,
> Conor.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 2/9] perf/arm-cmn: Avoid explicit cpumask var allocation from stack
From: Robin Murphy @ 2024-04-05 14:30 UTC (permalink / raw)
  To: Dawei Li, will, mark.rutland
  Cc: xueshuai, renyu.zj, yangyicong, jonathan.cameron, andersson,
	konrad.dybcio, linux-arm-kernel, linux-kernel, linux-arm-msm
In-Reply-To: <20240402105610.1695644-3-dawei.li@shingroup.cn>

On 2024-04-02 11:56 am, Dawei Li wrote:
> For CONFIG_CPUMASK_OFFSTACK=y kernel, explicit allocation of cpumask
> variable on stack is not recommended since it can cause potential stack
> overflow.
> 
> Instead, kernel code should always use *cpumask_var API(s) to allocate
> cpumask var in config- neutral way, leaving allocation strategy to
> CONFIG_CPUMASK_OFFSTACK.
> 
> Use *cpumask_var API(s) to address it.

I think the temporary mask may simply be redundant anyway. It seems like 
I may have misunderstood, and cpumask_of_node() actually only covers 
online CPUs already.

Thanks,
Robin.

> Signed-off-by: Dawei Li <dawei.li@shingroup.cn>
> ---
>   drivers/perf/arm-cmn.c | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
> index 7ef9c7e4836b..7278fd72d3da 100644
> --- a/drivers/perf/arm-cmn.c
> +++ b/drivers/perf/arm-cmn.c
> @@ -1949,21 +1949,26 @@ static int arm_cmn_pmu_offline_cpu(unsigned int cpu, struct hlist_node *cpuhp_no
>   {
>   	struct arm_cmn *cmn;
>   	unsigned int target;
> +	cpumask_var_t mask;
>   	int node;
> -	cpumask_t mask;
>   
>   	cmn = hlist_entry_safe(cpuhp_node, struct arm_cmn, cpuhp_node);
>   	if (cpu != cmn->cpu)
>   		return 0;
>   
> +	if (!alloc_cpumask_var(&mask, GFP_KERNEL))
> +		return 0;
> +
>   	node = dev_to_node(cmn->dev);
> -	if (cpumask_and(&mask, cpumask_of_node(node), cpu_online_mask) &&
> -	    cpumask_andnot(&mask, &mask, cpumask_of(cpu)))
> -		target = cpumask_any(&mask);
> +	if (cpumask_and(mask, cpumask_of_node(node), cpu_online_mask) &&
> +	    cpumask_andnot(mask, mask, cpumask_of(cpu)))
> +		target = cpumask_any(mask);
>   	else
>   		target = cpumask_any_but(cpu_online_mask, cpu);
>   	if (target < nr_cpu_ids)
>   		arm_cmn_migrate(cmn, target);
> +
> +	free_cpumask_var(mask);
>   	return 0;
>   }
>   

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [syzbot] [hardening?] [mm?] BUG: bad usercopy in fpa_set
From: Tetsuo Handa @ 2024-04-05 14:28 UTC (permalink / raw)
  To: Russell King (Oracle), Kees Cook
  Cc: Linux ARM, syzbot, linux-kernel, syzkaller-bugs
In-Reply-To: <Zg1/1xbmrY4yDfhO@shell.armlinux.org.uk>

On 2024/04/04 1:12, Russell King (Oracle) wrote:
> Therefore, there is _no way_ for fpa_set() to overwrite anything
> outside of thread_info->fpstate, because sizeof(struct user_fp)
> is smaller than sizeof(thread->fpstate).
> 
> Syzbot appears to be wrong in this instance.
> 

Thanks for clarification.

I came to suspect that commit 08626a6056aa ("arm: Implement thread_struct
whitelist for hardened usercopy") missed that ptrace(PTRACE_SETFPREGS)
needs to declare a usercopy whitelist. It seems to me that
https://syzkaller.appspot.com/text?tag=Patch&x=14c42099180000 can fix
this problem, but I'm not sure whether this is safe/correct. Can you check?


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v15 2/8] phy: Add HDMI configuration options
From: Vinod Koul @ 2024-04-05 14:24 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Alexander Stein, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Kishon Vijay Abraham I,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Sandor Yu, dri-devel, devicetree, linux-kernel, linux-phy, imx,
	linux-arm-kernel, linux, Dmitry Baryshkov
In-Reply-To: <20240306-inquisitive-funny-bull-017550@houat>

On 06-03-24, 15:48, Maxime Ripard wrote:
> Hi Alexander,
> 
> On Wed, Mar 06, 2024 at 11:16:19AM +0100, Alexander Stein wrote:
> > From: Sandor Yu <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@nxp.com>
> > Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > Acked-by: Vinod Koul <vkoul@kernel.org>
> > ---
> >  include/linux/phy/phy-hdmi.h | 24 ++++++++++++++++++++++++
> >  include/linux/phy/phy.h      |  7 ++++++-
> >  2 files changed, 30 insertions(+), 1 deletion(-)
> >  create mode 100644 include/linux/phy/phy-hdmi.h
> > 
> > diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h
> > new file mode 100644
> > index 0000000000000..b7de88e9090f0
> > --- /dev/null
> > +++ b/include/linux/phy/phy-hdmi.h
> > @@ -0,0 +1,24 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright 2022 NXP
> > + */
> > +
> > +#ifndef __PHY_HDMI_H_
> > +#define __PHY_HDMI_H_
> > +
> > +#include <linux/hdmi.h>
> > +/**
> > + * struct phy_configure_opts_hdmi - HDMI configuration set
> > + * @pixel_clk_rate: Pixel clock of video modes in KHz.
> > + * @bpc: Maximum bits per color channel.
> > + * @color_space: Colorspace in enum hdmi_colorspace.
> > + *
> > + * This structure is used to represent the configuration state of a HDMI phy.
> > + */
> > +struct phy_configure_opts_hdmi {
> > +	unsigned int pixel_clk_rate;
> > +	unsigned int bpc;
> > +	enum hdmi_colorspace color_space;
> > +};
> 
> Does the PHY actually care about the pixel clock rate, color space and
> formats, or does it only care about the character rate?

Nope it should not

-- 
~Vinod

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 0/2] Enable JPEG encoding on rk3588
From: Link Mauve @ 2024-04-05 14:21 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Emmanuel Gil Peyrot, linux-kernel, Ezequiel Garcia, Philipp Zabel,
	Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Heiko Stuebner, Joerg Roedel, Will Deacon,
	Robin Murphy, Sebastian Reichel, Cristian Ciocaltea, Dragan Simic,
	Shreeya Patel, Chris Morgan, Andy Yan, Nicolas Frattaroli,
	linux-media, linux-rockchip, devicetree, linux-arm-kernel, iommu
In-Reply-To: <bbcb66e9499120a86b367e7abdac2d8e2e704bfb.camel@ndufresne.ca>

On Thu, Apr 04, 2024 at 01:41:15PM -0400, Nicolas Dufresne wrote:
> Hi,

Hi,

> 
> Le mercredi 27 mars 2024 à 14:41 +0100, Emmanuel Gil Peyrot a écrit :
> > Only the JPEG encoder is available for now, although there are patches
> > for the undocumented VP8 encoder floating around[0].
> 
> [0] seems like a broken link. The VP8 encoder RFC is for RK3399 (and Hantro H1
> posted by ST more recently). The TRM says "VEPU121(JPEG encoder only)", which
> suggest that the H.264 and VP8 encoders usually found on the VEPU121 are
> removed. As Rockchip have remove the synthesize register while modifying the H1
> IP, it is difficult to verify. Confusingly the H.264 specific registers are
> documented in the TRM around VEPU121.

Ah, the link became, and was indeed ST’s series:
https://patchwork.kernel.org/project/linux-rockchip/list/?series=789885&archive=both

But the TRM part 1 says the VEPU121 supports H.264 encoding (page 367),
and it’s likely they didn’t remove just VP8 support since the codec
features are pretty close to H.264’s.

> 
> > 
> > This has been tested on a rock-5b, resulting in four /dev/video*
> > encoders.  The userspace program I’ve been using to test them is
> > Onix[1], using the jpeg-encoder example, it will pick one of these four
> > at random (but displays the one it picked):
> > % ffmpeg -i <input image> -pix_fmt yuvj420p temp.yuv
> > % jpeg-encoder temp.yuv <width> <height> NV12 <quality> output.jpeg
> 
> I don't like that we exposing each identical cores a separate video nodes. I
> think we should aim for 1 device, and then multi-plex and schedule de cores from
> inside the Linux kernel.

I agree, but this should be handled in the driver not in the device
tree, and it can be done later.

> 
> Not doing this now means we'll never have an optimal hardware usage
> distribution. Just consider two userspace software wanting to do jpeg encoding.
> If they both take a guess, they may endup using a single core. Where with proper
> scheduling in V4L2, the kernel will be able to properly distribute the load. I
> insist on this, since if we merge you changes it becomes an ABI and we can't
> change it anymore.

Will it really become ABI just like that?  Userspace should always
discover the video nodes and their capabilities and not hardcode e.g. a
specific /dev/videoN file for a specific codec.  I would argue that this
series would let userspace do JPEG encoding right away, even if in a
less optimal way than if the driver would round-robin them through a
single video node, but that can always be added in a future version.

> 
> I understand that this impose a rework of the mem2mem framework so that we can
> run multiple jobs, but this will be needed anyway on RK3588, since the rkvdec2,
> which we don't have a driver yet is also multi-core, but you need to use 2 cores
> when the resolution is close to 8K.

I think the mediatek JPEG driver already supports that, would it be ok
to do it the same way?

> 
> Nicolas
> 
> > 
> > [0] https://patchwork.kernel.org/project/linux-rockchip/list/?series=789885
> > [1] https://crates.io/crates/onix
> > 
> > Changes since v1:
> > - Dropped patches 1 and 4.
> > - Use the proper compatible form, since this device should be fully
> >   compatible with the VEPU of rk356x.
> > - Describe where the VEPU121 name comes from, and list other encoders
> >   and decoders present in this SoC.
> > - Properly test the device tree changes, I previously couldn’t since I
> >   was using a too recent version of python-jsonschema…
> > 
> > Emmanuel Gil Peyrot (2):
> >   media: dt-binding: media: Document rk3588’s VEPU121
> >   arm64: dts: rockchip: Add VEPU121 to rk3588
> > 
> >  .../bindings/media/rockchip,rk3568-vepu.yaml  |  8 +-
> >  arch/arm64/boot/dts/rockchip/rk3588s.dtsi     | 80 +++++++++++++++++++
> >  2 files changed, 86 insertions(+), 2 deletions(-)
> > 
> 

-- 
Link Mauve

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: (subset) [PATCH 1/7] drm/display: Select DRM_KMS_HELPER for DP helpers
From: Maxime Ripard @ 2024-04-05 13:09 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Daniel Vetter,
	Jani Nikula, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Javier Martinez Canillas, Russell King, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Chen-Yu Tsai,
	Samuel Holland, Catalin Marinas, Will Deacon, Thomas Bogendoerfer,
	Maxime Ripard
  Cc: Mark Brown, Alexander Stein, dri-devel, linux-kernel,
	linux-arm-kernel, imx, linux-sunxi, linux-mips, kernel test robot
In-Reply-To: <20240403-fix-dw-hdmi-kconfig-v1-1-afbc4a835c38@kernel.org>

On Wed, 03 Apr 2024 12:56:19 +0200, Maxime Ripard wrote:
> The DisplayPort helpers rely on some
> (__drm_atomic_helper_private_obj_duplicate_state,
> drm_kms_helper_hotplug_event) helpers found in files compiled by
> DRM_KMS_HELPER.
> 
> Prior to commit d674858ff979 ("drm/display: Make all helpers visible and
> switch to depends on"), DRM_DISPLAY_DP_HELPER was only selectable so it
> wasn't really a big deal. However, since that commit, it's now something
> that can be enabled as is, and since there's no expressed dependency
> with DRM_KMS_HELPER, it can break too.
> 
> [...]

Applied to misc/kernel.git (drm-misc-next).

Thanks!
Maxime


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: (subset) [PATCH 2/7] drm/bridge: dw-hdmi: Make DRM_DW_HDMI selectable
From: Maxime Ripard @ 2024-04-05 13:09 UTC (permalink / raw)
  To: Maarten Lankhorst, Thomas Zimmermann, David Airlie, Daniel Vetter,
	Jani Nikula, Andrzej Hajda, Neil Armstrong, Robert Foss,
	Laurent Pinchart, Jonas Karlman, Jernej Skrabec,
	Javier Martinez Canillas, Russell King, Shawn Guo, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Chen-Yu Tsai,
	Samuel Holland, Catalin Marinas, Will Deacon, Thomas Bogendoerfer,
	Maxime Ripard
  Cc: Mark Brown, Alexander Stein, dri-devel, linux-kernel,
	linux-arm-kernel, imx, linux-sunxi, linux-mips
In-Reply-To: <20240403-fix-dw-hdmi-kconfig-v1-2-afbc4a835c38@kernel.org>

On Wed, 03 Apr 2024 12:56:20 +0200, Maxime Ripard wrote:
> Commit c0e0f139354c ("drm: Make drivers depends on DRM_DW_HDMI") turned
> select dependencies into depends on ones. However, DRM_DW_HDMI was not
> manually selectable which resulted in no way to enable the drivers that
> were now depending on it.
> 
> 

Applied to misc/kernel.git (drm-misc-next).

Thanks!
Maxime


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 21/25] drivers: media: i2c: imx258: Use macros
From: Tommaso Merciai @ 2024-04-05 14:11 UTC (permalink / raw)
  To: Luis Garcia
  Cc: Sakari Ailus, linux-media, dave.stevenson, jacopo.mondi, mchehab,
	robh, krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
	festevam, devicetree, imx, linux-arm-kernel, linux-kernel, pavel,
	phone-devel, Ondrej Jirman
In-Reply-To: <082190a8-7ac5-4240-9a16-6b9168c67d57@luigi311.com>

Hi Luis,

On Fri, Apr 05, 2024 at 04:33:38AM -0600, Luis Garcia wrote:
> On 4/4/24 00:46, Sakari Ailus wrote:
> > On Wed, Apr 03, 2024 at 01:17:26PM -0600, Luigi311 wrote:
> >> On 4/3/24 10:23, Sakari Ailus wrote:
> >>> Hi Luis,
> >>>
> >>> On Wed, Apr 03, 2024 at 09:03:50AM -0600, git@luigi311.com wrote:
> >>>> From: Luis Garcia <git@luigi311.com>
> >>>>
> >>>> Use understandable macros instead of raw values.
> >>>>
> >>>> Signed-off-by: Ondrej Jirman <megi@xff.cz>
> >>>> Signed-off-by: Luis Garcia <git@luigi311.com>
> >>>> ---
> >>>>  drivers/media/i2c/imx258.c | 434 ++++++++++++++++++-------------------
> >>>>  1 file changed, 207 insertions(+), 227 deletions(-)
> >>>>
> >>>> diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
> >>>> index e2ecf6109516..30352c33f63c 100644
> >>>> --- a/drivers/media/i2c/imx258.c
> >>>> +++ b/drivers/media/i2c/imx258.c
> >>>> @@ -33,8 +33,6 @@
> >>>>  #define IMX258_VTS_30FPS_VGA		0x034c
> >>>>  #define IMX258_VTS_MAX			65525
> >>>>  
> >>>> -#define IMX258_REG_VTS			0x0340
> >>>> -
> >>>>  /* HBLANK control - read only */
> >>>>  #define IMX258_PPL_DEFAULT		5352
> >>>>  
> >>>> @@ -90,6 +88,53 @@
> >>>>  #define IMX258_PIXEL_ARRAY_WIDTH	4208U
> >>>>  #define IMX258_PIXEL_ARRAY_HEIGHT	3120U
> >>>>  
> >>>> +/* regs */
> >>>> +#define IMX258_REG_PLL_MULT_DRIV                  0x0310
> >>>> +#define IMX258_REG_IVTPXCK_DIV                    0x0301
> >>>> +#define IMX258_REG_IVTSYCK_DIV                    0x0303
> >>>> +#define IMX258_REG_PREPLLCK_VT_DIV                0x0305
> >>>> +#define IMX258_REG_IOPPXCK_DIV                    0x0309
> >>>> +#define IMX258_REG_IOPSYCK_DIV                    0x030b
> >>>> +#define IMX258_REG_PREPLLCK_OP_DIV                0x030d
> >>>> +#define IMX258_REG_PHASE_PIX_OUTEN                0x3030
> >>>> +#define IMX258_REG_PDPIX_DATA_RATE                0x3032
> >>>> +#define IMX258_REG_SCALE_MODE                     0x0401
> >>>> +#define IMX258_REG_SCALE_MODE_EXT                 0x3038
> >>>> +#define IMX258_REG_AF_WINDOW_MODE                 0x7bcd
> >>>> +#define IMX258_REG_FRM_LENGTH_CTL                 0x0350
> >>>> +#define IMX258_REG_CSI_LANE_MODE                  0x0114
> >>>> +#define IMX258_REG_X_EVN_INC                      0x0381
> >>>> +#define IMX258_REG_X_ODD_INC                      0x0383
> >>>> +#define IMX258_REG_Y_EVN_INC                      0x0385
> >>>> +#define IMX258_REG_Y_ODD_INC                      0x0387
> >>>> +#define IMX258_REG_BINNING_MODE                   0x0900
> >>>> +#define IMX258_REG_BINNING_TYPE_V                 0x0901
> >>>> +#define IMX258_REG_FORCE_FD_SUM                   0x300d
> >>>> +#define IMX258_REG_DIG_CROP_X_OFFSET              0x0408
> >>>> +#define IMX258_REG_DIG_CROP_Y_OFFSET              0x040a
> >>>> +#define IMX258_REG_DIG_CROP_IMAGE_WIDTH           0x040c
> >>>> +#define IMX258_REG_DIG_CROP_IMAGE_HEIGHT          0x040e
> >>>> +#define IMX258_REG_SCALE_M                        0x0404
> >>>> +#define IMX258_REG_X_OUT_SIZE                     0x034c
> >>>> +#define IMX258_REG_Y_OUT_SIZE                     0x034e
> >>>> +#define IMX258_REG_X_ADD_STA                      0x0344
> >>>> +#define IMX258_REG_Y_ADD_STA                      0x0346
> >>>> +#define IMX258_REG_X_ADD_END                      0x0348
> >>>> +#define IMX258_REG_Y_ADD_END                      0x034a
> >>>> +#define IMX258_REG_EXCK_FREQ                      0x0136
> >>>> +#define IMX258_REG_CSI_DT_FMT                     0x0112
> >>>> +#define IMX258_REG_LINE_LENGTH_PCK                0x0342
> >>>> +#define IMX258_REG_SCALE_M_EXT                    0x303a
> >>>> +#define IMX258_REG_FRM_LENGTH_LINES               0x0340
> >>>> +#define IMX258_REG_FINE_INTEG_TIME                0x0200
> >>>> +#define IMX258_REG_PLL_IVT_MPY                    0x0306
> >>>> +#define IMX258_REG_PLL_IOP_MPY                    0x030e
> >>>> +#define IMX258_REG_REQ_LINK_BIT_RATE_MBPS_H       0x0820
> >>>> +#define IMX258_REG_REQ_LINK_BIT_RATE_MBPS_L       0x0822
> >>>> +
> >>>> +#define REG8(a, v) { a, v }
> >>>> +#define REG16(a, v) { a, ((v) >> 8) & 0xff }, { (a) + 1, (v) & 0xff }
> >>>
> >>> The patch is nice but these macros are better replaced by the V4L2 CCI
> >>> helper that also offers register access functions. Could you add a patch to
> >>> convert the driver to use it (maybe after this one)?
> >>>
> >>
> >> Ohh perfect, using something else would be great. Ill go ahead and see
> >> if I can get that working.
> > 
> > Thanks. It may be easier to just do it in this one actually. Up to you.
> > 
> 
> I've made the swap but looks like its not playing nice with my ppp,
> its causing a crash and showing a call trace as soon as it does its
> first read to check the identity. I went in and dropped the cci_read
> and left it with the original implementation and I'm getting a very
> similar crash with cci_write too so it looks like its not liking
> how I'm implementing it. Looking at the few other drivers that were
> swapped over to use that, I don't seem to be missing anything. It's
> a big change so its not really something I can describe what I've
> changed but I do have the change on my github here
> https://github.com/luigi311/linux/commit/840593acb20eee87ce361e6929edf51eefbbe737

I checked your commit to switch to cci helper.
I think you are missing the right cci regmap initialization.

Please take care to use: devm_cci_regmap_init_i2c

/**
 * devm_cci_regmap_init_i2c() - Create regmap to use with cci_*() register
 *                              access functions
 *
 * @client: i2c_client to create the regmap for
 * @reg_addr_bits: register address width to use (8 or 16)
 *
 * Note the memory for the created regmap is devm() managed, tied to the client.
 *
 * Return: %0 on success or a negative error code on failure.
 */

Check drivers/media/i2c/imx290.c:1530
Hope this help :)

Note:
Somewhere into the github commit you are reading 16bit reg and storing
that into 64bit val. Take care! :)

Thanks & Regards,
Tommaso


> if you can provide some guidance, if not I can skip this change
> all together and we can do a separate attempt at swapping over to it.
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] arm64: Fix double TCR_T0SZ_OFFSET shift
From: Robin Murphy @ 2024-04-05 14:10 UTC (permalink / raw)
  To: Seongsu Park, catalin.marinas, will, ardb, mark.rutland
  Cc: linux-arm-kernel, linux-kernel, Leem ChaeHoon, Gyeonggeon Choi,
	Soomin Cho, DaeRo Lee, kmasta
In-Reply-To: <20240402104735.170539-1-sgsu.park@samsung.com>

On 2024-04-02 11:47 am, Seongsu Park wrote:
> We have already shifted the value of t0sz in TCR_T0SZ by TCR_T0SZ_OFFSET.
> So, the TCR_T0SZ_OFFSET shift here should be removed.

If the shift for assigning the t0sz value to the TCR field is wrong, 
then the other shift for comparing the same t0sz value to the existing 
TCR field must also be wrong. Really, this many people involved in 
writing a patch and still nobody spotted the obvious?

Thanks,
Robin.

> Co-developed-by: Leem ChaeHoon <infinite.run@gamil.com>
> Signed-off-by: Leem ChaeHoon <infinite.run@gamil.com>
> Co-developed-by: Gyeonggeon Choi <gychoi@student.42seoul.kr>
> Signed-off-by: Gyeonggeon Choi <gychoi@student.42seoul.kr>
> Co-developed-by: Soomin Cho <to.soomin@gmail.com>
> Signed-off-by: Soomin Cho <to.soomin@gmail.com>
> Co-developed-by: DaeRo Lee <skseofh@gmail.com>
> Signed-off-by: DaeRo Lee <skseofh@gmail.com>
> Co-developed-by: kmasta <kmasta.study@gmail.com>
> Signed-off-by: kmasta <kmasta.study@gmail.com>
> Signed-off-by: Seongsu Park <sgsu.park@samsung.com>
> ---
>   arch/arm64/include/asm/mmu_context.h | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
> index c768d16b81a4..58de99836d2e 100644
> --- a/arch/arm64/include/asm/mmu_context.h
> +++ b/arch/arm64/include/asm/mmu_context.h
> @@ -76,7 +76,7 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
>   		return;
>   
>   	tcr &= ~TCR_T0SZ_MASK;
> -	tcr |= t0sz << TCR_T0SZ_OFFSET;
> +	tcr |= t0sz;
>   	write_sysreg(tcr, tcr_el1);
>   	isb();
>   }

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 03/18] PCI: endpoint: Introduce pci_epc_mem_map()/unmap()
From: Niklas Cassel @ 2024-04-05 14:10 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: Manivannan Sadhasivam, Lorenzo Pieralisi, Kishon Vijay Abraham I,
	Shawn Lin, Krzysztof Wilczyński, Bjorn Helgaas,
	Heiko Stuebner, linux-pci, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, devicetree, linux-rockchip, linux-arm-kernel,
	Rick Wertenbroek, Wilfred Mallawa
In-Reply-To: <20240330041928.1555578-4-dlemoal@kernel.org>

On Sat, Mar 30, 2024 at 01:19:13PM +0900, Damien Le Moal wrote:
> Introduce the function pci_epc_mem_map() to facilitate controller memory
> address allocation and mapping to a RC PCI address region in endpoint
> function drivers.
> 
> This function first uses pci_epc_map_align() to determine the controller
> memory address alignment (offset and size) constraints. The result of
> this function is used to allocate a controller physical memory region
> using pci_epc_mem_alloc_addr() and map it to the RC PCI address
> space with pci_epc_map_addr(). Since pci_epc_map_align() may indicate
> that a mapping can be smaller than the requested size, pci_epc_mem_map()
> may only partially map the RC PCI address region specified and return
> a smaller size for the effective mapping.
> 
> The counterpart of pci_epc_mem_map() to unmap and free the controller
> memory address region is pci_epc_mem_unmap().
> 
> Both functions operate using struct pci_epc_map data structure which is
> extended to contain the physical and virtual addresses of the allocated
> controller memory. Endpoint function drivers can use struct pci_epc_map
> to implement read/write accesses within the mapped RC PCI address region
> using the ->virt_addr and ->size fields.
> 
> This commit contains contributions from Rick Wertenbroek
> <rick.wertenbroek@gmail.com>.
> 
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---
>  drivers/pci/endpoint/pci-epc-core.c | 68 +++++++++++++++++++++++++++++
>  include/linux/pci-epc.h             |  6 +++
>  2 files changed, 74 insertions(+)
> 
> diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
> index 37758ca91d7f..0095b54bdf9e 100644
> --- a/drivers/pci/endpoint/pci-epc-core.c
> +++ b/drivers/pci/endpoint/pci-epc-core.c
> @@ -530,6 +530,74 @@ int pci_epc_map_addr(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
>  }
>  EXPORT_SYMBOL_GPL(pci_epc_map_addr);
>  
> +/**
> + * pci_epc_mem_map() - allocate and map CPU address to PCI address
> + * @epc: the EPC device on which the CPU address is to be allocated and mapped
> + * @func_no: the physical endpoint function number in the EPC device
> + * @vfunc_no: the virtual endpoint function number in the physical function
> + * @pci_addr: PCI address to which the CPU address should be mapped
> + * @size: the number of bytes to map starting from @pci_addr
> + * @map: where to return the mapping information
> + *
> + * Allocate a controller physical address region and map it to a RC PCI address
> + * region, taking into account the controller physical address mapping
> + * constraints (if any). Returns the effective size of the mapping, which may
> + * be less than @size, or a negative error code in case of error.
> + */
> +ssize_t pci_epc_mem_map(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> +			u64 pci_addr, size_t size, struct pci_epc_map *map)
> +{
> +	int ret;
> +
> +	ret = pci_epc_map_align(epc, func_no, vfunc_no, pci_addr, size, map);
> +	if (ret)
> +		return ret;
> +
> +	map->virt_base = pci_epc_mem_alloc_addr(epc, &map->phys_base,
> +						map->map_size);
> +	if (!map->virt_base)
> +		return -ENOMEM;
> +
> +	map->phys_addr = map->phys_base + map->map_ofst;
> +	map->virt_addr = map->virt_base + map->map_ofst;
> +
> +	ret = pci_epc_map_addr(epc, func_no, vfunc_no, map->phys_base,
> +			       map->map_pci_addr, map->map_size);
> +	if (ret) {
> +		pci_epc_mem_free_addr(epc, map->phys_base, map->virt_base,
> +				      map->map_size);
> +		return ret;
> +	}
> +
> +	return map->pci_size;

map->pci_size is of type size_t.
pci_epc_mem_map returns a type of ssize_t.

This means that on ILP32 you will truncate the result, and will only be
able to map a region of max size 2GB.

Could we perhaps change this function to return an int instead?
(0 on success). The mapped size can still be accessed in map->pci_size.


Kind regards,
Niklas

> +}
> +EXPORT_SYMBOL_GPL(pci_epc_mem_map);
> +
> +/**
> + * pci_epc_mem_unmap() - unmap from PCI address and free a CPU address region
> + * @epc: the EPC device on which the CPU address is allocated and mapped
> + * @func_no: the physical endpoint function number in the EPC device
> + * @vfunc_no: the virtual endpoint function number in the physical function
> + * @map: the mapping information
> + *
> + * Allocate and map local CPU address to a PCI address, accounting for the
> + * controller local CPU address alignment constraints.
> + */
> +void pci_epc_mem_unmap(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> +		       struct pci_epc_map *map)
> +{
> +	if (!pci_epc_function_is_valid(epc, func_no, vfunc_no))
> +		return;
> +
> +	if (!map || !map->pci_size)
> +		return;
> +
> +	pci_epc_unmap_addr(epc, func_no, vfunc_no, map->phys_base);
> +	pci_epc_mem_free_addr(epc, map->phys_base, map->virt_base,
> +			      map->map_size);
> +}
> +EXPORT_SYMBOL_GPL(pci_epc_mem_unmap);
> +
>  /**
>   * pci_epc_clear_bar() - reset the BAR
>   * @epc: the EPC device for which the BAR has to be cleared
> diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
> index 8cfb4aaf2628..86397a500b54 100644
> --- a/include/linux/pci-epc.h
> +++ b/include/linux/pci-epc.h
> @@ -304,4 +304,10 @@ void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
>  				     phys_addr_t *phys_addr, size_t size);
>  void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
>  			   void __iomem *virt_addr, size_t size);
> +
> +ssize_t pci_epc_mem_map(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> +			u64 pci_addr, size_t size, struct pci_epc_map *map);
> +void pci_epc_mem_unmap(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
> +		       struct pci_epc_map *map);
> +
>  #endif /* __LINUX_PCI_EPC_H */
> -- 
> 2.44.0
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 2/2] phy: add driver for MediaTek XFI T-PHY
From: Vinod Koul @ 2024-04-05 14:06 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Bc-bocun Chen, Steven Liu, John Crispin, Chunfeng Yun,
	Kishon Vijay Abraham I, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
	Qingfang Deng, SkyLake Huang, Philipp Zabel, linux-arm-kernel,
	linux-mediatek, linux-phy, devicetree, linux-kernel, netdev
In-Reply-To: <ZgXPSrcj0egvzmS6@makrotopia.org>

On 28-03-24, 20:12, Daniel Golle wrote:
> Hi Vinod,
> 
> thank you for taking your time to review my submission!
> 
> On Fri, Mar 29, 2024 at 12:22:47AM +0530, Vinod Koul wrote:
> > On 10-02-24, 02:10, Daniel Golle wrote:
> > > Add driver for MediaTek's XFI T-PHY which can be found in the MT7988
> > 
> > What does XFI mean?
> 
> https://en.wikipedia.org/wiki/XFP_transceiver#XFI
> 
> I chose this name because names of functions dealing with the phy in
> the vendor driver are prefixed "xfi_pextp_".
> The register space used by the phy is called "pextp", which could be
> read as "_P_CI _ex_press _T_-_P_hy", and that is quite misleading as
> this phy isn't used for anything related to PCIe, so I wanted to find
> a better name.
> 
> XFI is still somehow related (as in: you would find the relevant
> places using grep in the vendor driver when looking for that) and
> seemed to at least somehow be aligned with the function of that phy:
> Dealing with (up to) 10 Gbit/s Ethernet SerDes signals.
> 
> MediaTek calls phys with more than one potential use T-PHY or X-PHY:
> The capital letter 'T' graphically connects 3 points, two of them
> being on the upper side representing the internal components and one
> on the lower side representing the single external interface.
> 
> Other vendors (like Marvell) call such things "combo phys".
> 
> Anyway, if anyone has better ideas regarding the naming, now is the
> moment to speak up ;)

This is fine. Combo phys are more common for ones dealing with multiple
components. I am fine either way. But it is good to document why this
was named as such

> 
> 
> > 
> > > SoC. The XFI T-PHY is a 10 Gigabit/s Ethernet SerDes PHY with muxes on
> > > the internal side to be used with either USXGMII PCS or LynxI PCS,
> > > depending on the selected PHY interface mode.
> > > 
> > > The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> > > PHY_INTERFACE_MODE_* corresponding to the supported modes:
> > > 
> > >  * USXGMII                 \
> > >  * 10GBase-R                }- USXGMII PCS - XGDM  \
> > >  * 5GBase-R                /                        \
> > >                                                      }- Ethernet MAC
> > >  * 2500Base-X              \                        /
> > >  * 1000Base-X               }- LynxI PCS - GDM     /
> > >  * Cisco SGMII (MAC side)  /
> > > 
> > > In order to work-around a performance issue present on the first of
> > > two XFI T-PHYs present in MT7988, special tuning is applied which can be
> > > selected by adding the 'mediatek,usxgmii-performance-errata' property to
> > > the device tree node.
> > > 
> > > There is no documentation for most registers used for the
> > > analog/tuning part, however, most of the registers have been partially
> > > reverse-engineered from MediaTek's SDK implementation (an opaque
> > > sequence of 32-bit register writes) and descriptions for all relevant
> > > digital registers and bits such as resets and muxes have been supplied
> > > by MediaTek.
> > > 
> > > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > > Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> > > ---
> > > v3: no changes
> > > v2:
> > >  * use IO helpers from mtk-io.h instead of rolling my own
> > >  * use devm_clk_bulk_get()
> > >  * yse devm_platform_ioremap_resource()
> > >  * unify name and description everywhere
> > >  * invert bool is_xgmii into bool use_lynxi_pcs and add comments
> > >    describing the meaning of each of the stack variables
> > >  * not much we can do about remaining magic values unless MTK provides
> > >    definitions for them
> > > 
> > > 
> > >  MAINTAINERS                             |   1 +
> > >  drivers/phy/mediatek/Kconfig            |  12 +
> > >  drivers/phy/mediatek/Makefile           |   1 +
> > >  drivers/phy/mediatek/phy-mtk-xfi-tphy.c | 360 ++++++++++++++++++++++++
> > >  4 files changed, 374 insertions(+)
> > >  create mode 100644 drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > > 
> > > diff --git a/MAINTAINERS b/MAINTAINERS
> > > index 4be2fd097f261..616b86e3e62fd 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -13776,6 +13776,7 @@ L:	netdev@vger.kernel.org
> > >  S:	Maintained
> > >  F:	drivers/net/phy/mediatek-ge-soc.c
> > >  F:	drivers/net/phy/mediatek-ge.c
> > > +F:	drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > >  
> > >  MEDIATEK I2C CONTROLLER DRIVER
> > >  M:	Qii Wang <qii.wang@mediatek.com>
> > > diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> > > index 3849b7c87d287..117d0e84c7360 100644
> > > --- a/drivers/phy/mediatek/Kconfig
> > > +++ b/drivers/phy/mediatek/Kconfig
> > > @@ -13,6 +13,18 @@ config PHY_MTK_PCIE
> > >  	  callback for PCIe GEN3 port, it supports software efuse
> > >  	  initialization.
> > >  
> > > +config PHY_MTK_XFI_TPHY
> > > +	tristate "MediaTek 10GE SerDes XFI T-PHY driver"
> > > +	depends on ARCH_MEDIATEK || COMPILE_TEST
> > > +	depends on OF && OF_ADDRESS
> > 
> > why both, is OF not enough?
> 
> As we are already also depending on HAS_IOMEM what is left there is
> basically just a !SPARC dependency.
> And that is probably a historic left-over and (according to commit
> 5ab5fc7e35705c from 2010...) should be re-evaluated. I'm happy to drop
> OF_ADDRESS and keep only HAS_IOMEM, and we shall see if any of the
> COMPILE_TESTs actually fails, given that everyone is fine with that.

Yeah HAS_IOMEM would be required for it to get compiled on diff archs. I
think OF should suffice... wdyt?

> 
> > 
> > > +	depends on HAS_IOMEM
> > > +	select GENERIC_PHY
> > > +	help
> > > +	  Say 'Y' here to add support for MediaTek XFI T-PHY driver.
> > > +	  The driver provides access to the Ethernet SerDes T-PHY supporting
> > > +	  1GE and 2.5GE modes via the LynxI PCS, and 5GE and 10GE modes
> > > +	  via the USXGMII PCS found in MediaTek SoCs with 10G Ethernet.
> > > +
> > >  config PHY_MTK_TPHY
> > >  	tristate "MediaTek T-PHY Driver"
> > >  	depends on ARCH_MEDIATEK || COMPILE_TEST
> > > diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> > > index f6e24a47e0815..1b8088df71e84 100644
> > > --- a/drivers/phy/mediatek/Makefile
> > > +++ b/drivers/phy/mediatek/Makefile
> > > @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
> > >  obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
> > >  obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
> > >  obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
> > > +obj-$(CONFIG_PHY_MTK_XFI_TPHY)		+= phy-mtk-xfi-tphy.o
> > >  
> > >  phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
> > >  phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
> > > diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > > new file mode 100644
> > > index 0000000000000..551d6cee33f94
> > > --- /dev/null
> > > +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c
> > > @@ -0,0 +1,360 @@
> > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > +/* MediaTek 10GE SerDes XFI T-PHY driver
> > > + *
> > > + * Copyright (c) 2024 Daniel Golle <daniel@makrotopia.org>
> > > + *                    Bc-bocun Chen <bc-bocun.chen@mediatek.com>
> > > + * based on mtk_usxgmii.c and mtk_sgmii.c found in MediaTek's SDK (GPL-2.0)
> > > + * Copyright (c) 2022 MediaTek Inc.
> > > + * Author: Henry Yen <henry.yen@mediatek.com>
> > > + */
> > > +
> > > +#include <linux/module.h>
> > > +#include <linux/device.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/of.h>
> > > +#include <linux/io.h>
> > > +#include <linux/clk.h>
> > > +#include <linux/reset.h>
> > > +#include <linux/phy.h>
> > > +#include <linux/phy/phy.h>
> > > +
> > > +#include "phy-mtk-io.h"
> > > +
> > > +#define MTK_XFI_TPHY_NUM_CLOCKS		2
> > > +
> > > +#define REG_DIG_GLB_70			0x0070
> > > +#define  XTP_PCS_RX_EQ_IN_PROGRESS(x)	FIELD_PREP(GENMASK(25, 24), (x))
> > > +#define  XTP_PCS_MODE_MASK		GENMASK(17, 16)
> > > +#define  XTP_PCS_MODE(x)		FIELD_PREP(GENMASK(17, 16), (x))
> > > +#define  XTP_PCS_RST_B			BIT(15)
> > > +#define  XTP_FRC_PCS_RST_B		BIT(14)
> > > +#define  XTP_PCS_PWD_SYNC_MASK		GENMASK(13, 12)
> > > +#define  XTP_PCS_PWD_SYNC(x)		FIELD_PREP(XTP_PCS_PWD_SYNC_MASK, (x))
> > > +#define  XTP_PCS_PWD_ASYNC_MASK		GENMASK(11, 10)
> > > +#define  XTP_PCS_PWD_ASYNC(x)		FIELD_PREP(XTP_PCS_PWD_ASYNC_MASK, (x))
> > > +#define  XTP_FRC_PCS_PWD_ASYNC		BIT(8)
> > > +#define  XTP_PCS_UPDT			BIT(4)
> > > +#define  XTP_PCS_IN_FR_RG		BIT(0)
> > > +
> > > +#define REG_DIG_GLB_F4			0x00f4
> > > +#define  XFI_DPHY_PCS_SEL		BIT(0)
> > > +#define   XFI_DPHY_PCS_SEL_SGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 1)
> > > +#define   XFI_DPHY_PCS_SEL_USXGMII	FIELD_PREP(XFI_DPHY_PCS_SEL, 0)
> > > +#define  XFI_DPHY_AD_SGDT_FRC_EN	BIT(5)
> > > +
> > > +#define REG_DIG_LN_TRX_40		0x3040
> > > +#define  XTP_LN_FRC_TX_DATA_EN		BIT(29)
> > > +#define  XTP_LN_TX_DATA_EN		BIT(28)
> > > +
> > > +#define REG_DIG_LN_TRX_B0		0x30b0
> > > +#define  XTP_LN_FRC_TX_MACCK_EN		BIT(5)
> > > +#define  XTP_LN_TX_MACCK_EN		BIT(4)
> > > +
> > > +#define REG_ANA_GLB_D0			0x90d0
> > > +#define  XTP_GLB_USXGMII_SEL_MASK	GENMASK(3, 1)
> > > +#define  XTP_GLB_USXGMII_SEL(x)		FIELD_PREP(GENMASK(3, 1), (x))
> > > +#define  XTP_GLB_USXGMII_EN		BIT(0)
> > > +
> > > +struct mtk_xfi_tphy {
> > > +	void __iomem		*base;
> > > +	struct device		*dev;
> > > +	struct reset_control	*reset;
> > > +	struct clk_bulk_data	clocks[MTK_XFI_TPHY_NUM_CLOCKS];
> > > +	bool			da_war;
> > > +};
> > > +
> > > +static void mtk_xfi_tphy_setup(struct mtk_xfi_tphy *xfi_tphy,
> > > +			       phy_interface_t interface)
> > > +{
> > > +	/* Override 10GBase-R tuning value if work-around is selected */
> > > +	bool da_war = (xfi_tphy->da_war && (interface == PHY_INTERFACE_MODE_10GBASER));
> > 
> > why do you need braces around this?
> 
> Just for readability. They can safely be removed.
> 
> > 
> > > +	/* Bools to make setting up values for specific PHY speeds easier */
> > > +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> > > +	bool is_1g = (interface == PHY_INTERFACE_MODE_1000BASEX ||
> > > +		      interface == PHY_INTERFACE_MODE_SGMII);
> > > +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> > > +		       interface == PHY_INTERFACE_MODE_USXGMII);
> > > +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> > > +	/* Bool to configure input mux to either
> > > +	 *  - USXGMII PCS (64b/66b coding) for 5G/10G
> > > +	 *  - LynxI PCS (8b/10b coding) for 1G/2.5G
> > > +	 */
> > > +	bool use_lynxi_pcs = (is_1g || is_2p5g);
> > 
> > This is quite terrible to read, how about declaring variables first and
> > then doing the initialization?
> 
> Ack.
> 
> > 
> > > +
> > > +	dev_dbg(xfi_tphy->dev, "setting up for mode %s\n", phy_modes(interface));
> > > +
> > > +	/* Setup PLL setting */
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x9024, 0x100000, is_10g ? 0x0 : 0x100000);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x2020, 0x202000, is_5g ? 0x202000 : 0x0);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x2030, 0x500, is_1g ? 0x0 : 0x500);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x2034, 0xa00, is_1g ? 0x0 : 0xa00);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x2040, 0x340000, is_1g ? 0x200000 : 0x140000);
> > 
> > magic numbers?
> 
> Yes, and not much we can do about them. According to MTK engineers (in
> Cc) they also don't know what those numbers really mean in detail and
> have only been given sequences of magic register writes for each
> interface mode ([1], [2], [3], [4], [5]) by the upstream IP supplier
> of the PHY. I then compared those write sequences with each others,
> and observed the behavior of each register (as in: read their value
> before and after the write operation; all of them read back the value
> written to them) and rewrote the initialization as one function only
> changing the bits actually needed (instead of always writing the complete
> 32-bit value). I've made sure that everything still works and Bc-bocun
> Chen of MediaTek (also in Cc) then helped to label at least some of
> the registers and bits there in as far as they are understood by
> MediaTek.
> 
> [1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c#172
> [2]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c#284
> [3]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c#132
> [4]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c#246
> [5]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/21.02/files/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c#360

Okay lets document the source of magic values so that people may refer
to these

> 
> > 
> > > +
> > > +	/* Setup RXFE BW setting */
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x50f0, 0xc10, is_1g ? 0x410 : is_5g ? 0x800 : 0x400);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x50e0, 0x4000, is_5g ? 0x0 : 0x4000);
> > > +
> > > +	/* Setup RX CDR setting */
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x506c, 0x30000, is_5g ? 0x0 : 0x30000);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x5070, 0x670000, is_5g ? 0x620000 : 0x50000);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x5074, 0x180000, is_5g ? 0x180000 : 0x0);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x5078, 0xf000400, is_5g ? 0x8000000 :
> > > +									0x7000400);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x507c, 0x5000500, is_5g ? 0x4000400 :
> > > +									0x1000100);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x5080, 0x1410, is_1g ? 0x400 : is_5g ? 0x1010 : 0x0);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x5084, 0x30300, is_1g ? 0x30300 :
> > > +							      is_5g ? 0x30100 :
> > > +								      0x100);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x5088, 0x60200, is_1g ? 0x20200 :
> > > +							      is_5g ? 0x40000 :
> > > +								      0x20000);
> > > +
> > > +	/* Setting RXFE adaptation range setting */
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x50e4, 0xc0000, is_5g ? 0x0 : 0xc0000);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x50e8, 0x40000, is_5g ? 0x0 : 0x40000);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x50ec, 0xa00, is_1g ? 0x200 : 0x800);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x50a8, 0xee0000, is_5g ? 0x800000 :
> > > +								       0x6e0000);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x6004, 0x190000, is_5g ? 0x0 : 0x190000);
> > > +
> > > +	if (is_10g)
> > > +		writel(0x01423342, xfi_tphy->base + 0x00f8);
> > > +	else if (is_5g)
> > > +		writel(0x00a132a1, xfi_tphy->base + 0x00f8);
> > > +	else if (is_2p5g)
> > > +		writel(0x009c329c, xfi_tphy->base + 0x00f8);
> > > +	else
> > > +		writel(0x00fa32fa, xfi_tphy->base + 0x00f8);
> > > +
> > > +	/* Force SGDT_OUT off and select PCS */
> > > +	mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_F4,
> > > +			    XFI_DPHY_AD_SGDT_FRC_EN | XFI_DPHY_PCS_SEL,
> > > +			    XFI_DPHY_AD_SGDT_FRC_EN |
> > > +			    (use_lynxi_pcs ? XFI_DPHY_PCS_SEL_SGMII :
> > > +					     XFI_DPHY_PCS_SEL_USXGMII));
> > > +
> > > +	/* Force GLB_CKDET_OUT */
> > > +	mtk_phy_set_bits(xfi_tphy->base + 0x0030, 0xc00);
> > > +
> > > +	/* Force AEQ on */
> > > +	writel(XTP_PCS_RX_EQ_IN_PROGRESS(2) | XTP_PCS_PWD_SYNC(2) | XTP_PCS_PWD_ASYNC(2),
> > > +	       xfi_tphy->base + REG_DIG_GLB_70);
> > > +
> > > +	usleep_range(1, 5);
> > > +
> > > +	/* Setup TX DA default value */
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x30b0, 0x30, 0x20);
> > > +	writel(0x00008a01, xfi_tphy->base + 0x3028);
> > > +	writel(0x0000a884, xfi_tphy->base + 0x302c);
> > > +	writel(0x00083002, xfi_tphy->base + 0x3024);
> > > +
> > > +	/* Setup RG default value */
> > > +	if (use_lynxi_pcs) {
> > > +		writel(0x00011110, xfi_tphy->base + 0x3010);
> > > +		writel(0x40704000, xfi_tphy->base + 0x3048);
> > > +	} else {
> > > +		writel(0x00022220, xfi_tphy->base + 0x3010);
> > > +		writel(0x0f020a01, xfi_tphy->base + 0x5064);
> > > +		writel(0x06100600, xfi_tphy->base + 0x50b4);
> > > +		if (interface == PHY_INTERFACE_MODE_USXGMII)
> > > +			writel(0x40704000, xfi_tphy->base + 0x3048);
> > > +		else
> > > +			writel(0x47684100, xfi_tphy->base + 0x3048);
> > > +	}
> > > +
> > > +	if (is_1g)
> > > +		writel(0x0000c000, xfi_tphy->base + 0x3064);
> > > +
> > > +	/* Setup RX EQ initial value */
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x3050, 0xa8000000,
> > > +			    (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xa8000000 : 0x0);
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0x3054, 0xaa,
> > > +			    (interface != PHY_INTERFACE_MODE_10GBASER) ? 0xaa : 0x0);
> > > +
> > > +	if (!use_lynxi_pcs)
> > > +		writel(0x00000f00, xfi_tphy->base + 0x306c);
> > > +	else if (is_2p5g)
> > > +		writel(0x22000f00, xfi_tphy->base + 0x306c);
> > > +	else
> > > +		writel(0x20200f00, xfi_tphy->base + 0x306c);
> > > +
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0xa008, 0x10000, da_war ? 0x10000 : 0x0);
> > > +
> > > +	mtk_phy_update_bits(xfi_tphy->base + 0xa060, 0x50000, use_lynxi_pcs ? 0x50000 : 0x40000);
> > > +
> > > +	/* Setup PHYA speed */
> > > +	mtk_phy_update_bits(xfi_tphy->base + REG_ANA_GLB_D0,
> > > +			    XTP_GLB_USXGMII_SEL_MASK | XTP_GLB_USXGMII_EN,
> > > +			    is_10g ?  XTP_GLB_USXGMII_SEL(0) :
> > > +			    is_5g ?   XTP_GLB_USXGMII_SEL(1) :
> > > +			    is_2p5g ? XTP_GLB_USXGMII_SEL(2) :
> > > +				      XTP_GLB_USXGMII_SEL(3));
> > > +	mtk_phy_set_bits(xfi_tphy->base + REG_ANA_GLB_D0, XTP_GLB_USXGMII_EN);
> > > +
> > > +	/* Release reset */
> > > +	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_GLB_70,
> > > +			 XTP_PCS_RST_B | XTP_FRC_PCS_RST_B);
> > > +	usleep_range(150, 500);
> > > +
> > > +	/* Switch to P0 */
> > > +	mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
> > > +			    XTP_PCS_IN_FR_RG |
> > > +			    XTP_FRC_PCS_PWD_ASYNC |
> > > +			    XTP_PCS_PWD_ASYNC_MASK |
> > > +			    XTP_PCS_PWD_SYNC_MASK |
> > > +			    XTP_PCS_UPDT,
> > > +			    XTP_PCS_IN_FR_RG |
> > > +			    XTP_FRC_PCS_PWD_ASYNC |
> > > +			    XTP_PCS_UPDT);
> > > +	usleep_range(1, 5);
> > > +
> > > +	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
> > > +	usleep_range(15, 50);
> > > +
> > > +	if (use_lynxi_pcs) {
> > > +		/* Switch to Gen2 */
> > > +		mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
> > > +				    XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> > > +				    XTP_PCS_MODE(1) | XTP_PCS_UPDT);
> > > +	} else {
> > > +		/* Switch to Gen3 */
> > > +		mtk_phy_update_bits(xfi_tphy->base + REG_DIG_GLB_70,
> > > +				    XTP_PCS_MODE_MASK | XTP_PCS_UPDT,
> > > +				    XTP_PCS_MODE(2) | XTP_PCS_UPDT);
> > > +	}
> > > +	usleep_range(1, 5);
> > > +
> > > +	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_70, XTP_PCS_UPDT);
> > > +
> > > +	usleep_range(100, 500);
> > > +
> > > +	/* Enable MAC CK */
> > > +	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_B0, XTP_LN_TX_MACCK_EN);
> > > +	mtk_phy_clear_bits(xfi_tphy->base + REG_DIG_GLB_F4, XFI_DPHY_AD_SGDT_FRC_EN);
> > > +
> > > +	/* Enable TX data */
> > > +	mtk_phy_set_bits(xfi_tphy->base + REG_DIG_LN_TRX_40,
> > > +			 XTP_LN_FRC_TX_DATA_EN | XTP_LN_TX_DATA_EN);
> > > +	usleep_range(400, 1000);
> > > +}
> > > +
> > > +static int mtk_xfi_tphy_set_mode(struct phy *phy, enum phy_mode mode, int
> > > +				 submode)
> > > +{
> > > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > > +
> > > +	if (mode != PHY_MODE_ETHERNET)
> > > +		return -EINVAL;
> > > +
> > > +	switch (submode) {
> > > +	case PHY_INTERFACE_MODE_1000BASEX:
> > > +	case PHY_INTERFACE_MODE_2500BASEX:
> > > +	case PHY_INTERFACE_MODE_SGMII:
> > > +	case PHY_INTERFACE_MODE_5GBASER:
> > > +	case PHY_INTERFACE_MODE_10GBASER:
> > > +	case PHY_INTERFACE_MODE_USXGMII:
> > > +		mtk_xfi_tphy_setup(xfi_tphy, submode);
> > > +		return 0;
> > > +	default:
> > > +		return -EINVAL;
> > > +	}
> > > +}
> > > +
> > > +static int mtk_xfi_tphy_reset(struct phy *phy)
> > > +{
> > > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > > +
> > > +	reset_control_assert(xfi_tphy->reset);
> > > +	usleep_range(100, 500);
> > > +	reset_control_deassert(xfi_tphy->reset);
> > > +	usleep_range(1, 10);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int mtk_xfi_tphy_power_on(struct phy *phy)
> > > +{
> > > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > > +
> > > +	return clk_bulk_prepare_enable(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> > > +}
> > > +
> > > +static int mtk_xfi_tphy_power_off(struct phy *phy)
> > > +{
> > > +	struct mtk_xfi_tphy *xfi_tphy = phy_get_drvdata(phy);
> > > +
> > > +	clk_bulk_disable_unprepare(MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static const struct phy_ops mtk_xfi_tphy_ops = {
> > > +	.power_on	= mtk_xfi_tphy_power_on,
> > > +	.power_off	= mtk_xfi_tphy_power_off,
> > > +	.set_mode	= mtk_xfi_tphy_set_mode,
> > > +	.reset		= mtk_xfi_tphy_reset,
> > > +	.owner		= THIS_MODULE,
> > > +};
> > > +
> > > +static int mtk_xfi_tphy_probe(struct platform_device *pdev)
> > > +{
> > > +	struct device_node *np = pdev->dev.of_node;
> > > +	struct phy_provider *phy_provider;
> > > +	struct mtk_xfi_tphy *xfi_tphy;
> > > +	struct phy *phy;
> > > +	int ret;
> > > +
> > > +	if (!np)
> > > +		return -ENODEV;
> > > +
> > > +	xfi_tphy = devm_kzalloc(&pdev->dev, sizeof(*xfi_tphy), GFP_KERNEL);
> > > +	if (!xfi_tphy)
> > > +		return -ENOMEM;
> > > +
> > > +	xfi_tphy->base = devm_platform_ioremap_resource(pdev, 0);
> > > +	if (IS_ERR(xfi_tphy->base))
> > > +		return PTR_ERR(xfi_tphy->base);
> > > +
> > > +	xfi_tphy->dev = &pdev->dev;
> > > +	xfi_tphy->clocks[0].id = "topxtal";
> > > +	xfi_tphy->clocks[1].id = "xfipll";
> > > +	ret = devm_clk_bulk_get(&pdev->dev, MTK_XFI_TPHY_NUM_CLOCKS, xfi_tphy->clocks);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	xfi_tphy->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> > > +	if (IS_ERR(xfi_tphy->reset))
> > > +		return PTR_ERR(xfi_tphy->reset);
> > > +
> > > +	xfi_tphy->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
> > > +
> > > +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_xfi_tphy_ops);
> > > +	if (IS_ERR(phy))
> > > +		return PTR_ERR(phy);
> > > +
> > > +	phy_set_drvdata(phy, xfi_tphy);
> > > +	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
> > > +
> > > +	return PTR_ERR_OR_ZERO(phy_provider);
> > > +}
> > > +
> > > +static const struct of_device_id mtk_xfi_tphy_match[] = {
> > > +	{ .compatible = "mediatek,mt7988-xfi-tphy", },
> > > +	{ /* sentinel */ }
> > > +};
> > > +MODULE_DEVICE_TABLE(of, mtk_xfi_tphy_match);
> > > +
> > > +static struct platform_driver mtk_xfi_tphy_driver = {
> > > +	.probe = mtk_xfi_tphy_probe,
> > > +	.driver = {
> > > +		.name = "mtk-xfi-tphy",
> > > +		.of_match_table = mtk_xfi_tphy_match,
> > > +	},
> > > +};
> > > +module_platform_driver(mtk_xfi_tphy_driver);
> > > +
> > > +MODULE_DESCRIPTION("MediaTek 10GE SerDes XFI T-PHY driver");
> > > +MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
> > > +MODULE_AUTHOR("Bc-bocun Chen <bc-bocun.chen@mediatek.com>");
> > > +MODULE_LICENSE("GPL");
> > > -- 
> > > 2.43.0
> > 
> > -- 
> > ~Vinod

-- 
~Vinod

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 6/9] drm: xlnx: zynqmp_dpsub: Set input live format
From: Tomi Valkeinen @ 2024-04-05 12:56 UTC (permalink / raw)
  To: Anatoliy Klymenko
  Cc: dri-devel, linux-arm-kernel, linux-kernel, devicetree,
	linux-media, Laurent Pinchart, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Daniel Vetter, Michal Simek,
	Andrzej Hajda, Neil Armstrong, Robert Foss, Jonas Karlman,
	Jernej Skrabec, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Mauro Carvalho Chehab
In-Reply-To: <20240321-dp-live-fmt-v3-6-d5090d796b7e@amd.com>

On 21/03/2024 22:43, Anatoliy Klymenko wrote:
> Program live video input format according to selected media bus format.
> 
> In the bridge mode of operation, DPSUB is connected to FPGA CRTC which
> almost certainly supports a single media bus format as its output. Expect
> this to be delivered via the new bridge atomic state. Program DPSUB
> registers accordingly. Update zynqmp_disp_layer_set_format() API to fit
> both live and non-live layer types.
> 
> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
> ---
>   drivers/gpu/drm/xlnx/zynqmp_disp.c | 66 +++++++++++++++++++++++++-------------
>   drivers/gpu/drm/xlnx/zynqmp_disp.h |  2 +-
>   drivers/gpu/drm/xlnx/zynqmp_dp.c   | 13 +++++---
>   drivers/gpu/drm/xlnx/zynqmp_kms.c  |  2 +-
>   4 files changed, 55 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> index 0c2b3f4bffa6..a385d22d428e 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> @@ -436,19 +436,28 @@ static void zynqmp_disp_avbuf_set_format(struct zynqmp_disp *disp,
>   					 const struct zynqmp_disp_format *fmt)
>   {
>   	unsigned int i;
> -	u32 val;
> +	u32 val, reg;
>   
> -	val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_FMT);
> -	val &= zynqmp_disp_layer_is_video(layer)
> -	    ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
> -	    : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK;
> -	val |= fmt->buf_fmt;
> -	zynqmp_disp_avbuf_write(disp, ZYNQMP_DISP_AV_BUF_FMT, val);
> +	layer->disp_fmt = fmt;
> +	if (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE) {
> +		reg = ZYNQMP_DISP_AV_BUF_FMT;
> +		val = zynqmp_disp_avbuf_read(disp, ZYNQMP_DISP_AV_BUF_FMT);
> +		val &= zynqmp_disp_layer_is_video(layer)
> +		    ? ~ZYNQMP_DISP_AV_BUF_FMT_NL_VID_MASK
> +		    : ~ZYNQMP_DISP_AV_BUF_FMT_NL_GFX_MASK;
> +		val |= fmt->buf_fmt;
> +	} else {
> +		reg = zynqmp_disp_layer_is_video(layer)
> +		    ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
> +		    : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
> +		val = fmt->buf_fmt;
> +	}
> +	zynqmp_disp_avbuf_write(disp, reg, val);

Just write the registers inside the above if-else blocks.

>   
>   	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; i++) {
> -		unsigned int reg = zynqmp_disp_layer_is_video(layer)
> -				 ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF(i)
> -				 : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF(i);
> +		reg = zynqmp_disp_layer_is_video(layer)
> +		    ? ZYNQMP_DISP_AV_BUF_VID_COMP_SF(i)
> +		    : ZYNQMP_DISP_AV_BUF_GFX_COMP_SF(i);
>   
>   		zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
>   	}
> @@ -902,25 +911,33 @@ static void zynqmp_disp_audio_disable(struct zynqmp_disp *disp)
>    */
>   
>   /**
> - * zynqmp_disp_layer_find_format - Find format information for a DRM format
> + * zynqmp_disp_layer_find_format - Find format information for a DRM or media
> + * bus format
>    * @layer: The layer
> - * @drm_fmt: DRM format to search
> + * @drm_or_bus_format: DRM or media bus format
>    *
>    * Search display subsystem format information corresponding to the given DRM
> - * format @drm_fmt for the @layer, and return a pointer to the format
> - * descriptor.
> + * or media bus format @drm_or_bus_format for the @layer, and return a pointer
> + * to the format descriptor. Search key choice depends on @layer mode, for live
> + * layers search is done by zynqmp_disp_format.bus_fmt, and for non-live layers
> + * zynqmp_disp_format.drm_fmt is used.

Here also I recommend creating separate funcs for the fourcc and mbus 
versions. They are different types, even if they happen to fit into u32.

>    *
>    * Return: A pointer to the format descriptor if found, NULL otherwise
>    */
>   static const struct zynqmp_disp_format *
>   zynqmp_disp_layer_find_format(struct zynqmp_disp_layer *layer,
> -			      u32 drm_fmt)
> +			      u32 drm_or_bus_format)
>   {
>   	unsigned int i;
> +	const struct zynqmp_disp_format *disp_format;
>   
>   	for (i = 0; i < layer->info->num_formats; i++) {
> -		if (layer->info->formats[i].drm_fmt == drm_fmt)
> -			return &layer->info->formats[i];
> +		disp_format = &layer->info->formats[i];
> +		if ((layer->mode == ZYNQMP_DPSUB_LAYER_LIVE &&
> +		     disp_format->bus_fmt == drm_or_bus_format) ||
> +		    (layer->mode == ZYNQMP_DPSUB_LAYER_NONLIVE &&
> +		     disp_format->drm_fmt == drm_or_bus_format))
> +			return disp_format;
>   	}
>   
>   	return NULL;
> @@ -992,20 +1009,25 @@ void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
>   /**
>    * zynqmp_disp_layer_set_format - Set the layer format
>    * @layer: The layer
> - * @info: The format info
> + * @drm_or_bus_format: DRM or media bus format
>    *
>    * Set the format for @layer to @info. The layer must be disabled.
>    */
>   void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
> -				  const struct drm_format_info *info)
> +				  u32 drm_or_bus_format)

And here, with a quick look, a separate function would be fine.

  Tomi

>   {
>   	unsigned int i;
>   
> -	layer->disp_fmt = zynqmp_disp_layer_find_format(layer, info->format);
> -	layer->drm_fmt = info;
> +	layer->disp_fmt = zynqmp_disp_layer_find_format(layer, drm_or_bus_format);
> +	if (WARN_ON(!layer->disp_fmt))
> +		return;
>   
>   	zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);
>   
> +	layer->drm_fmt = drm_format_info(layer->disp_fmt->drm_fmt);
> +	if (!layer->drm_fmt)
> +		return;
> +
>   	if (layer->mode == ZYNQMP_DPSUB_LAYER_LIVE)
>   		return;
>   
> @@ -1013,7 +1035,7 @@ void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
>   	 * Set pconfig for each DMA channel to indicate they're part of a
>   	 * video group.
>   	 */
> -	for (i = 0; i < info->num_planes; i++) {
> +	for (i = 0; i < layer->drm_fmt->num_planes; i++) {
>   		struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
>   		struct xilinx_dpdma_peripheral_config pconfig = {
>   			.video_group = true,
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.h b/drivers/gpu/drm/xlnx/zynqmp_disp.h
> index 88c285a12e23..9f9a5f50ffbc 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.h
> @@ -55,7 +55,7 @@ u32 *zynqmp_disp_layer_formats(struct zynqmp_disp_layer *layer,
>   void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer);
>   void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer);
>   void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
> -				  const struct drm_format_info *info);
> +				  u32 drm_or_bus_format);
>   int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
>   			     struct drm_plane_state *state);
>   
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index e3b9eb3d9273..200e63636006 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1299,15 +1299,20 @@ static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
>   				  struct drm_bridge_state *old_bridge_state)
>   {
>   	struct zynqmp_disp_layer *layer;
> -	const struct drm_format_info *info;
> +	struct drm_bridge_state *bridge_state;
> +	u32 bus_fmt;
>   
>   	layer = zynqmp_dp_disp_connected_live_layer(dp);
>   	if (!layer)
>   		return;
>   
> -	/* TODO: Make the format configurable. */
> -	info = drm_format_info(DRM_FORMAT_YUV422);
> -	zynqmp_disp_layer_set_format(layer, info);
> +	bridge_state = drm_atomic_get_new_bridge_state(old_bridge_state->base.state,
> +						       old_bridge_state->bridge);
> +	if (WARN_ON(!bridge_state))
> +		return;
> +
> +	bus_fmt = bridge_state->input_bus_cfg.format;
> +	zynqmp_disp_layer_set_format(layer, bus_fmt);
>   	zynqmp_disp_layer_enable(layer);
>   
>   	if (layer == dp->dpsub->layers[ZYNQMP_DPSUB_LAYER_GFX])
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c b/drivers/gpu/drm/xlnx/zynqmp_kms.c
> index bf9fba01df0e..d96b3f3f2e3a 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
> @@ -111,7 +111,7 @@ static void zynqmp_dpsub_plane_atomic_update(struct drm_plane *plane,
>   		if (old_state->fb)
>   			zynqmp_disp_layer_disable(layer);
>   
> -		zynqmp_disp_layer_set_format(layer, new_state->fb->format);
> +		zynqmp_disp_layer_set_format(layer, new_state->fb->format->format);
>   	}
>   
>   	zynqmp_disp_layer_update(layer, new_state);
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 05/18] PCI: endpoint: test: Synchronously cancel command handler work
From: Niklas Cassel @ 2024-04-05 13:41 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Damien Le Moal, Lorenzo Pieralisi, Kishon Vijay Abraham I,
	Shawn Lin, Krzysztof Wilczyński, Bjorn Helgaas,
	Heiko Stuebner, linux-pci, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, devicetree, linux-rockchip, linux-arm-kernel,
	Rick Wertenbroek, Wilfred Mallawa
In-Reply-To: <20240403074702.GD25309@thinkpad>

On Wed, Apr 03, 2024 at 01:17:02PM +0530, Manivannan Sadhasivam wrote:
> On Sat, Mar 30, 2024 at 01:19:15PM +0900, Damien Le Moal wrote:
> > Replace the call to cancel_delayed_work() with a call to
> > cancel_delayed_work_sync() in pci_epf_test_unbind(). This ensures that
> > the command handler is really stopped when proceeding with dma and bar
> > cleanup.
> > 
> > Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> 
> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> 
> - Mani
> 
> > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > ---

Reviewed-by: Niklas Cassel <cassel@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 06/18] PCI: endpoint: test: Implement link_down event operation
From: Niklas Cassel @ 2024-04-05 13:39 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Damien Le Moal, Lorenzo Pieralisi, Kishon Vijay Abraham I,
	Shawn Lin, Krzysztof Wilczyński, Bjorn Helgaas,
	Heiko Stuebner, linux-pci, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, devicetree, linux-rockchip, linux-arm-kernel,
	Rick Wertenbroek, Wilfred Mallawa
In-Reply-To: <20240403074823.GE25309@thinkpad>

On Wed, Apr 03, 2024 at 01:18:23PM +0530, Manivannan Sadhasivam wrote:
> On Sat, Mar 30, 2024 at 01:19:16PM +0900, Damien Le Moal wrote:
> > Implement the link_down event operation to stop the command execution
> > delayed work when the endpoint controller notifies a link down event.
> > 
> > Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> 
> This patch is already part of another series I posted [1] and under review. So
> this can be dropped.
> 
> - Mani
> 
> [1] https://lore.kernel.org/linux-pci/20240401-pci-epf-rework-v2-9-970dbe90b99d@linaro.org/

Mani, your patch does not use _sync(),
so I don't think that we can simply drop this patch.


Kind regards,
Niklas

> 
> > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > ---
> >  drivers/pci/endpoint/functions/pci-epf-test.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
> > index ab40c3182677..e6d4e1747c9f 100644
> > --- a/drivers/pci/endpoint/functions/pci-epf-test.c
> > +++ b/drivers/pci/endpoint/functions/pci-epf-test.c
> > @@ -824,9 +824,19 @@ static int pci_epf_test_link_up(struct pci_epf *epf)
> >  	return 0;
> >  }
> >  
> > +static int pci_epf_test_link_down(struct pci_epf *epf)
> > +{
> > +	struct pci_epf_test *epf_test = epf_get_drvdata(epf);
> > +
> > +	cancel_delayed_work_sync(&epf_test->cmd_handler);
> > +
> > +	return 0;
> > +}
> > +
> >  static const struct pci_epc_event_ops pci_epf_test_event_ops = {
> >  	.core_init = pci_epf_test_core_init,
> >  	.link_up = pci_epf_test_link_up,
> > +	.link_down = pci_epf_test_link_down,
> >  };
> >  
> >  static int pci_epf_test_alloc_space(struct pci_epf *epf)
> > -- 
> > 2.44.0
> > 
> 
> -- 
> மணிவண்ணன் சதாசிவம்

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2 3/6] firmware: arm_scmi: add initial support for i.MX BBM protocol
From: Peng Fan (OSS) @ 2024-04-05 12:39 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Sudeep Holla, Cristian Marussi
  Cc: Peng Fan, devicetree, imx, linux-arm-kernel, linux-kernel
In-Reply-To: <20240405-imx95-bbm-misc-v2-v2-0-9fc9186856c2@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

The i.MX BBM protocol is for managing i.MX BBM module which provides
RTC and BUTTON feature.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 drivers/firmware/arm_scmi/Kconfig      |  10 +
 drivers/firmware/arm_scmi/Makefile     |   1 +
 drivers/firmware/arm_scmi/imx-sm-bbm.c | 378 +++++++++++++++++++++++++++++++++
 include/linux/scmi_imx_protocol.h      |  45 ++++
 4 files changed, 434 insertions(+)

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index aa5842be19b2..56d11c9d9f47 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -181,3 +181,13 @@ config ARM_SCMI_POWER_CONTROL
 	  early shutdown/reboot SCMI requests.
 
 endmenu
+
+config IMX_SCMI_BBM_EXT
+	tristate "i.MX SCMI BBM EXTENSION"
+	depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF)
+	default y if ARCH_MXC
+	help
+	  This enables i.MX System BBM control logic which supports RTC
+	  and BUTTON.
+
+	  This driver can also be built as a module.
diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile
index a7bc4796519c..327687acf857 100644
--- a/drivers/firmware/arm_scmi/Makefile
+++ b/drivers/firmware/arm_scmi/Makefile
@@ -11,6 +11,7 @@ scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) += msg.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += virtio.o
 scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += optee.o
 scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o system.o voltage.o powercap.o
+scmi-protocols-$(CONFIG_IMX_SCMI_BBM_EXT) += imx-sm-bbm.o
 scmi-module-objs := $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transport-y)
 
 obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-core.o
diff --git a/drivers/firmware/arm_scmi/imx-sm-bbm.c b/drivers/firmware/arm_scmi/imx-sm-bbm.c
new file mode 100644
index 000000000000..92c0aedf65cc
--- /dev/null
+++ b/drivers/firmware/arm_scmi/imx-sm-bbm.c
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) NXP BBM Protocol
+ *
+ * Copyright 2024 NXP
+ */
+
+#define pr_fmt(fmt) "SCMI Notifications BBM - " fmt
+
+#include <linux/bits.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/scmi_protocol.h>
+#include <linux/scmi_imx_protocol.h>
+
+#include "protocols.h"
+#include "notify.h"
+
+#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x10000
+
+enum scmi_imx_bbm_protocol_cmd {
+	IMX_BBM_GPR_SET = 0x3,
+	IMX_BBM_GPR_GET = 0x4,
+	IMX_BBM_RTC_ATTRIBUTES = 0x5,
+	IMX_BBM_RTC_TIME_SET = 0x6,
+	IMX_BBM_RTC_TIME_GET = 0x7,
+	IMX_BBM_RTC_ALARM_SET = 0x8,
+	IMX_BBM_BUTTON_GET = 0x9,
+	IMX_BBM_RTC_NOTIFY = 0xA,
+	IMX_BBM_BUTTON_NOTIFY = 0xB,
+};
+
+#define GET_RTCS_NR(x)	le32_get_bits((x), GENMASK(23, 16))
+#define GET_GPRS_NR(x)	le32_get_bits((x), GENMASK(15, 0))
+
+#define SCMI_IMX_BBM_NOTIFY_RTC_UPDATED		BIT(2)
+#define SCMI_IMX_BBM_NOTIFY_RTC_ROLLOVER	BIT(1)
+#define SCMI_IMX_BBM_NOTIFY_RTC_ALARM		BIT(0)
+
+#define SCMI_IMX_BBM_RTC_ALARM_ENABLE_FLAG	BIT(0)
+
+#define SCMI_IMX_BBM_NOTIFY_RTC_FLAG	\
+	(SCMI_IMX_BBM_NOTIFY_RTC_UPDATED | SCMI_IMX_BBM_NOTIFY_RTC_ROLLOVER | \
+	 SCMI_IMX_BBM_NOTIFY_RTC_ALARM)
+
+#define SCMI_IMX_BBM_EVENT_RTC_MASK		GENMASK(31, 24)
+
+struct scmi_imx_bbm_info {
+	u32 version;
+	int nr_rtc;
+	int nr_gpr;
+};
+
+struct scmi_msg_imx_bbm_protocol_attributes {
+	__le32 attributes;
+};
+
+struct scmi_imx_bbm_set_time {
+	__le32 id;
+	__le32 flags;
+	__le32 value_low;
+	__le32 value_high;
+};
+
+struct scmi_imx_bbm_get_time {
+	__le32 id;
+	__le32 flags;
+};
+
+struct scmi_imx_bbm_alarm_time {
+	__le32 id;
+	__le32 flags;
+	__le32 value_low;
+	__le32 value_high;
+};
+
+struct scmi_msg_imx_bbm_rtc_notify {
+	__le32 rtc_id;
+	__le32 flags;
+};
+
+struct scmi_msg_imx_bbm_button_notify {
+	__le32 flags;
+};
+
+struct scmi_imx_bbm_notify_payld {
+	__le32 flags;
+};
+
+static int scmi_imx_bbm_attributes_get(const struct scmi_protocol_handle *ph,
+				       struct scmi_imx_bbm_info *pi)
+{
+	int ret;
+	struct scmi_xfer *t;
+	struct scmi_msg_imx_bbm_protocol_attributes *attr;
+
+	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0, sizeof(*attr), &t);
+	if (ret)
+		return ret;
+
+	attr = t->rx.buf;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret) {
+		pi->nr_rtc = GET_RTCS_NR(attr->attributes);
+		pi->nr_gpr = GET_GPRS_NR(attr->attributes);
+	}
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_notify(const struct scmi_protocol_handle *ph,
+			       u32 src_id, int message_id, bool enable)
+{
+	int ret;
+	struct scmi_xfer *t;
+
+	if (message_id == IMX_BBM_RTC_NOTIFY) {
+		struct scmi_msg_imx_bbm_rtc_notify *rtc_notify;
+
+		ret = ph->xops->xfer_get_init(ph, message_id,
+					      sizeof(*rtc_notify), 0, &t);
+		if (ret)
+			return ret;
+
+		rtc_notify = t->tx.buf;
+		rtc_notify->rtc_id = cpu_to_le32(0);
+		rtc_notify->flags =
+			cpu_to_le32(enable ? SCMI_IMX_BBM_NOTIFY_RTC_FLAG : 0);
+	} else if (message_id == IMX_BBM_BUTTON_NOTIFY) {
+		struct scmi_msg_imx_bbm_button_notify *button_notify;
+
+		ret = ph->xops->xfer_get_init(ph, message_id,
+					      sizeof(*button_notify), 0, &t);
+		if (ret)
+			return ret;
+
+		button_notify = t->tx.buf;
+		button_notify->flags = cpu_to_le32(enable ? 1 : 0);
+	} else {
+		return -EINVAL;
+	}
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+	return ret;
+}
+
+static enum scmi_imx_bbm_protocol_cmd evt_2_cmd[] = {
+	IMX_BBM_RTC_NOTIFY,
+	IMX_BBM_BUTTON_NOTIFY
+};
+
+static int scmi_imx_bbm_set_notify_enabled(const struct scmi_protocol_handle *ph,
+					   u8 evt_id, u32 src_id, bool enable)
+{
+	int ret, cmd_id;
+
+	if (evt_id >= ARRAY_SIZE(evt_2_cmd))
+		return -EINVAL;
+
+	cmd_id = evt_2_cmd[evt_id];
+	ret = scmi_imx_bbm_notify(ph, src_id, cmd_id, enable);
+	if (ret)
+		pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
+			 evt_id, src_id, ret);
+
+	return ret;
+}
+
+static void *scmi_imx_bbm_fill_custom_report(const struct scmi_protocol_handle *ph,
+					     u8 evt_id, ktime_t timestamp,
+					     const void *payld, size_t payld_sz,
+					     void *report, u32 *src_id)
+{
+	const struct scmi_imx_bbm_notify_payld *p = payld;
+	struct scmi_imx_bbm_notif_report *r = report;
+
+	if (sizeof(*p) != payld_sz)
+		return NULL;
+
+	if (evt_id == SCMI_EVENT_IMX_BBM_RTC) {
+		r->is_rtc = true;
+		r->is_button = false;
+		r->timestamp = timestamp;
+		r->rtc_id = le32_get_bits(p->flags, SCMI_IMX_BBM_EVENT_RTC_MASK);
+		r->rtc_evt = le32_get_bits(p->flags, SCMI_IMX_BBM_NOTIFY_RTC_FLAG);
+		dev_dbg(ph->dev, "RTC: %d evt: %x\n", r->rtc_id, r->rtc_evt);
+		*src_id = r->rtc_evt;
+	} else if (evt_id == SCMI_EVENT_IMX_BBM_BUTTON) {
+		r->is_rtc = false;
+		r->is_button = true;
+		r->timestamp = timestamp;
+		dev_dbg(ph->dev, "BBM Button\n");
+		*src_id = 0;
+	} else {
+		WARN_ON_ONCE(1);
+		return NULL;
+	}
+
+	return r;
+}
+
+static const struct scmi_event scmi_imx_bbm_events[] = {
+	{
+		.id = SCMI_EVENT_IMX_BBM_RTC,
+		.max_payld_sz = sizeof(struct scmi_imx_bbm_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_bbm_notif_report),
+	},
+	{
+		.id = SCMI_EVENT_IMX_BBM_BUTTON,
+		.max_payld_sz = sizeof(struct scmi_imx_bbm_notify_payld),
+		.max_report_sz = sizeof(struct scmi_imx_bbm_notif_report),
+	},
+};
+
+static const struct scmi_event_ops scmi_imx_bbm_event_ops = {
+	.set_notify_enabled = scmi_imx_bbm_set_notify_enabled,
+	.fill_custom_report = scmi_imx_bbm_fill_custom_report,
+};
+
+static const struct scmi_protocol_events scmi_imx_bbm_protocol_events = {
+	.queue_sz = SCMI_PROTO_QUEUE_SZ,
+	.ops = &scmi_imx_bbm_event_ops,
+	.evts = scmi_imx_bbm_events,
+	.num_events = ARRAY_SIZE(scmi_imx_bbm_events),
+	.num_sources = 1,
+};
+
+static int scmi_imx_bbm_protocol_init(const struct scmi_protocol_handle *ph)
+{
+	u32 version;
+	int ret;
+	struct scmi_imx_bbm_info *binfo;
+
+	ret = ph->xops->version_get(ph, &version);
+	if (ret)
+		return ret;
+
+	dev_info(ph->dev, "NXP SM BBM Version %d.%d\n",
+		 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+	binfo = devm_kzalloc(ph->dev, sizeof(*binfo), GFP_KERNEL);
+	if (!binfo)
+		return -ENOMEM;
+
+	ret = scmi_imx_bbm_attributes_get(ph, binfo);
+	if (ret)
+		return ret;
+
+	return ph->set_priv(ph, binfo, version);
+}
+
+static int scmi_imx_bbm_rtc_time_set(const struct scmi_protocol_handle *ph,
+				     u32 rtc_id, u64 sec)
+{
+	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
+	struct scmi_imx_bbm_set_time *cfg;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (rtc_id >= pi->nr_rtc)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, IMX_BBM_RTC_TIME_SET, sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(rtc_id);
+	cfg->flags = 0;
+	cfg->value_low = lower_32_bits(sec);
+	cfg->value_high = upper_32_bits(sec);
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_rtc_time_get(const struct scmi_protocol_handle *ph,
+				     u32 rtc_id, u64 *value)
+{
+	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
+	struct scmi_imx_bbm_get_time *cfg;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (rtc_id >= pi->nr_rtc)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, IMX_BBM_RTC_TIME_GET, sizeof(*cfg),
+				      sizeof(u64), &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(rtc_id);
+	cfg->flags = 0;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret)
+		*value = get_unaligned_le64(t->rx.buf);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_rtc_alarm_set(const struct scmi_protocol_handle *ph,
+				      u32 rtc_id, u64 sec)
+{
+	struct scmi_imx_bbm_info *pi = ph->get_priv(ph);
+	struct scmi_imx_bbm_alarm_time *cfg;
+	struct scmi_xfer *t;
+	int ret;
+
+	if (rtc_id >= pi->nr_rtc)
+		return -EINVAL;
+
+	ret = ph->xops->xfer_get_init(ph, IMX_BBM_RTC_ALARM_SET, sizeof(*cfg), 0, &t);
+	if (ret)
+		return ret;
+
+	cfg = t->tx.buf;
+	cfg->id = cpu_to_le32(rtc_id);
+	cfg->flags = SCMI_IMX_BBM_RTC_ALARM_ENABLE_FLAG;
+	cfg->value_low = lower_32_bits(sec);
+	cfg->value_high = upper_32_bits(sec);
+
+	ret = ph->xops->do_xfer(ph, t);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static int scmi_imx_bbm_button_get(const struct scmi_protocol_handle *ph, u32 *state)
+{
+	struct scmi_xfer *t;
+	int ret;
+
+	ret = ph->xops->xfer_get_init(ph, IMX_BBM_BUTTON_GET, 0, sizeof(u32), &t);
+	if (ret)
+		return ret;
+
+	ret = ph->xops->do_xfer(ph, t);
+	if (!ret)
+		*state = get_unaligned_le32(t->rx.buf);
+
+	ph->xops->xfer_put(ph, t);
+
+	return ret;
+}
+
+static const struct scmi_imx_bbm_proto_ops scmi_imx_bbm_proto_ops = {
+	.rtc_time_get = scmi_imx_bbm_rtc_time_get,
+	.rtc_time_set = scmi_imx_bbm_rtc_time_set,
+	.rtc_alarm_set = scmi_imx_bbm_rtc_alarm_set,
+	.button_get = scmi_imx_bbm_button_get,
+};
+
+static const struct scmi_protocol scmi_imx_bbm = {
+	.id = SCMI_PROTOCOL_IMX_BBM,
+	.owner = THIS_MODULE,
+	.instance_init = &scmi_imx_bbm_protocol_init,
+	.ops = &scmi_imx_bbm_proto_ops,
+	.events = &scmi_imx_bbm_protocol_events,
+	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
+};
+
+module_scmi_protocol(scmi_imx_bbm);
diff --git a/include/linux/scmi_imx_protocol.h b/include/linux/scmi_imx_protocol.h
new file mode 100644
index 000000000000..90ce011a4429
--- /dev/null
+++ b/include/linux/scmi_imx_protocol.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * SCMI Message Protocol driver NXP extension header
+ *
+ * Copyright 2024 NXP.
+ */
+
+#ifndef _LINUX_SCMI_NXP_PROTOCOL_H
+#define _LINUX_SCMI_NXP_PROTOCOL_H
+
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/notifier.h>
+#include <linux/types.h>
+
+enum scmi_nxp_protocol {
+	SCMI_PROTOCOL_IMX_BBM = 0x81,
+};
+
+struct scmi_imx_bbm_proto_ops {
+	int (*rtc_time_set)(const struct scmi_protocol_handle *ph, u32 id,
+			    uint64_t sec);
+	int (*rtc_time_get)(const struct scmi_protocol_handle *ph, u32 id,
+			    u64 *val);
+	int (*rtc_alarm_set)(const struct scmi_protocol_handle *ph, u32 id,
+			     u64 sec);
+	int (*button_get)(const struct scmi_protocol_handle *ph, u32 *state);
+};
+
+enum scmi_nxp_notification_events {
+	SCMI_EVENT_IMX_BBM_RTC = 0x0,
+	SCMI_EVENT_IMX_BBM_BUTTON = 0x1,
+	SCMI_EVENT_IMX_MISC_CONTROL_DISABLED = 0x0,
+	SCMI_EVENT_IMX_MISC_CONTROL_FALLING_EDGE = 0x1,
+	SCMI_EVENT_IMX_MISC_CONTROL_RISING_EDGE = 0x2,
+};
+
+struct scmi_imx_bbm_notif_report {
+	bool			is_rtc;
+	bool			is_button;
+	ktime_t			timestamp;
+	unsigned int		rtc_id;
+	unsigned int		rtc_evt;
+};
+#endif

-- 
2.37.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 3/4] arm64: Update AMU-based frequency scale factor on entering idle
From: Beata Michalska @ 2024-04-05 13:33 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, ionela.voinescu, vanshikonda
  Cc: sudeep.holla, will, catalin.marinas, vincent.guittot, sumitg,
	yang, lihuisong
In-Reply-To: <20240405133319.859813-1-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@os.amperecomputing.com>
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
---
 arch/arm64/kernel/topology.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index b03fe8617721..f204f6489f98 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -207,6 +207,19 @@ static struct scale_freq_data amu_sfd = {
 	.set_freq_scale = amu_scale_freq_tick,
 };
 
+void arch_cpu_idle_enter(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (!cpumask_test_cpu(cpu, amu_fie_cpus))
+		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_update, cpu)))
+		amu_scale_freq_tick();
+}
+
 #define AMU_SAMPLE_EXP_MS	20
 
 unsigned int arch_freq_get_on_cpu(int cpu)
@@ -232,8 +245,8 @@ unsigned int arch_freq_get_on_cpu(int cpu)
 	 * 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))) {
+	if (!housekeeping_cpu(cpu, HK_TYPE_TICK) || (!idle_cpu(cpu) &&
+	    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;
 
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 0/4] Add support for AArch64 AMUv1-based arch_freq_get_on_cpu
From: Beata Michalska @ 2024-04-05 13:33 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, ionela.voinescu, vanshikonda
  Cc: sudeep.holla, will, catalin.marinas, vincent.guittot, sumitg,
	yang, lihuisong

Introducing arm64 specific version of arch_freq_get_on_cpu, cashing on
existing implementation for FIE and AMUv1 support: the frequency scale
factor, updated on each sched tick, serves as a base for retrieving
the frequency for a given CPU, representing an average frequency
reported between the ticks - thus its accuracy is limited.

The changes have been rather lightly (due to some limitations) tested on
an FVP model. Note that some small discrepancies have been observed while
testing (on the model) and this is currently being investigated, though it
should not have any significant impact on the overall results.

Relevant discussions:
[1] https://lore.kernel.org/all/20240229162520.970986-1-vanshikonda@os.amperecomputing.com/
[2] https://lore.kernel.org/all/7eozim2xnepacnnkzxlbx34hib4otycnbn4dqymfziqou5lw5u@5xzpv3t7sxo3/
[3] https://lore.kernel.org/all/20231212072617.14756-1-lihuisong@huawei.com/
[4] https://lore.kernel.org/lkml/ZIHpd6unkOtYVEqP@e120325.cambridge.arm.com/T/#m4e74cb5a0aaa353c60fedc6cfb95ab7a6e381e3c

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


Beata Michalska (3):
  arm64: Provide an AMU-based version of arch_freq_get_on_cpu
  arm64: Update AMU-based frequency scale factor on entering idle
  cpufreq: Use arch specific feedback for cpuinfo_cur_freq

Ionela Voinescu (1):
  arch_topology: init capacity_freq_ref to 0

 arch/arm64/kernel/topology.c | 125 ++++++++++++++++++++++++++++++++---
 drivers/base/arch_topology.c |   8 ++-
 drivers/cpufreq/cpufreq.c    |   4 +-
 3 files changed, 123 insertions(+), 14 deletions(-)

-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v4 2/4] arm64: Provide an AMU-based version of arch_freq_get_on_cpu
From: Beata Michalska @ 2024-04-05 13:33 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, ionela.voinescu, vanshikonda
  Cc: sudeep.holla, will, catalin.marinas, vincent.guittot, sumitg,
	yang, lihuisong
In-Reply-To: <20240405133319.859813-1-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 current 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@arm.com>
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
---
 arch/arm64/kernel/topology.c | 112 +++++++++++++++++++++++++++++++----
 1 file changed, 102 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 1a2c72f3e7f8..b03fe8617721 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_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_update = jiffies;
 }
 
 static struct scale_freq_data amu_sfd = {
@@ -189,6 +207,80 @@ static struct scale_freq_data amu_sfd = {
 	.set_freq_scale = amu_scale_freq_tick,
 };
 
+#define AMU_SAMPLE_EXP_MS	20
+
+unsigned int arch_freq_get_on_cpu(int cpu)
+{
+	struct amu_cntr_sample *amu_sample;
+	cpumask_var_t ref_cpumask = NULL;
+	unsigned long last_update;
+	unsigned int freq;
+	u64 scale;
+
+	if (!cpumask_test_cpu(cpu, amu_fie_cpus) || !arch_scale_freq_ref(cpu))
+		return 0;
+retry:
+	amu_sample = per_cpu_ptr(&cpu_amu_samples, cpu);
+
+	last_update = amu_sample->last_update;
+
+	/*
+	 * For those CPUs that are in full dynticks mode,
+	 * and 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_is_shared(policy)) {
+			cpufreq_cpu_put(policy);
+			return 0;
+		}
+
+		if (!ref_cpumask) {
+			if (!zalloc_cpumask_var(&ref_cpumask, GFP_KERNEL)) {
+				cpufreq_cpu_put(policy);
+				return 0;
+			}
+
+			cpumask_copy(ref_cpumask, policy->cpus);
+		}
+
+		cpufreq_cpu_put(policy);
+
+		do {
+			cpumask_clear_cpu(ref_cpu, ref_cpumask);
+			ref_cpu = cpumask_first(ref_cpumask);
+
+		} while (ref_cpu < nr_cpu_ids && idle_cpu(ref_cpu));
+
+		if (ref_cpu >= nr_cpu_ids) {
+			/* No alternative to pull info from */
+			free_cpumask_var(ref_cpumask);
+			return 0;
+		}
+		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;
+
+	free_cpumask_var(ref_cpumask);
+
+	return freq;
+}
+
 static void amu_fie_setup(const struct cpumask *cpus)
 {
 	int cpu;
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v4 1/4] arch_topology: init capacity_freq_ref to 0
From: Beata Michalska @ 2024-04-05 13:33 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, ionela.voinescu, vanshikonda
  Cc: sudeep.holla, will, catalin.marinas, vincent.guittot, sumitg,
	yang, lihuisong
In-Reply-To: <20240405133319.859813-1-beata.michalska@arm.com>

From: Ionela Voinescu <ionela.voinescu@arm.com>

It's useful to have capacity_freq_ref initialized to 0 for users of
arch_scale_freq_ref() to detect when capacity_freq_ref was not
yet set.

The only scenario affected by this change in the init value is when a
cpufreq driver is never loaded. As a result, the only setter of a
cpu scale factor remains the call of topology_normalize_cpu_scale()
from parse_dt_topology(). There we cannot use the value 0 of
capacity_freq_ref so we have to compensate for its uninitialized state.

Signed-off-by: Ionela Voinescu <ionela.voinescu@arm.com>
Signed-off-by: Beata Michalska <beata.michalska@arm.com>
---
 drivers/base/arch_topology.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
index 024b78a0cfc1..7d4c92cd2bad 100644
--- a/drivers/base/arch_topology.c
+++ b/drivers/base/arch_topology.c
@@ -27,7 +27,7 @@
 static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data);
 static struct cpumask scale_freq_counters_mask;
 static bool scale_freq_invariant;
-DEFINE_PER_CPU(unsigned long, capacity_freq_ref) = 1;
+DEFINE_PER_CPU(unsigned long, capacity_freq_ref) = 0;
 EXPORT_PER_CPU_SYMBOL_GPL(capacity_freq_ref);
 
 static bool supports_scale_freq_counters(const struct cpumask *cpus)
@@ -292,13 +292,15 @@ void topology_normalize_cpu_scale(void)
 
 	capacity_scale = 1;
 	for_each_possible_cpu(cpu) {
-		capacity = raw_capacity[cpu] * per_cpu(capacity_freq_ref, cpu);
+		capacity = raw_capacity[cpu] *
+			   (per_cpu(capacity_freq_ref, cpu) ?: 1);
 		capacity_scale = max(capacity, capacity_scale);
 	}
 
 	pr_debug("cpu_capacity: capacity_scale=%llu\n", capacity_scale);
 	for_each_possible_cpu(cpu) {
-		capacity = raw_capacity[cpu] * per_cpu(capacity_freq_ref, cpu);
+		capacity = raw_capacity[cpu] *
+			   (per_cpu(capacity_freq_ref, cpu) ?: 1);
 		capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
 			capacity_scale);
 		topology_set_cpu_scale(cpu, capacity);
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v2 01/18] PCI: endpoint: Introduce pci_epc_function_is_valid()
From: Niklas Cassel @ 2024-04-05 13:33 UTC (permalink / raw)
  To: Damien Le Moal
  Cc: Manivannan Sadhasivam, Lorenzo Pieralisi, Kishon Vijay Abraham I,
	Shawn Lin, Krzysztof Wilczyński, Bjorn Helgaas,
	Heiko Stuebner, linux-pci, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, devicetree, linux-rockchip, linux-arm-kernel,
	Rick Wertenbroek, Wilfred Mallawa
In-Reply-To: <20240330041928.1555578-2-dlemoal@kernel.org>

On Sat, Mar 30, 2024 at 01:19:11PM +0900, Damien Le Moal wrote:
> Introduce the epc core helper function pci_epc_function_is_valid() to
> verify that an epc pointer, a physical function number and a virtual
> function number are all valid. This avoids repeating the code pattern:
> 
> if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
> 	return err;
> 
> if (vfunc_no > 0 && (!epc->max_vfs || vfunc_no > epc->max_vfs[func_no]))
> 	return err;
> 
> in many functions of the endpoint controller core code.
> 
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---

Reviewed-by: Niklas Cassel <cassel@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 19/25] media: i2c: imx258: Change register settings for variants of the sensor
From: Dave Stevenson @ 2024-04-05 13:16 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Luigi311, linux-media, jacopo.mondi, mchehab, robh,
	krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
	festevam, devicetree, imx, linux-arm-kernel, linux-kernel, pavel,
	phone-devel
In-Reply-To: <Zg_Zl0Q2kEDJoQoe@kekkonen.localdomain>

Hi Sakari

On Fri, 5 Apr 2024 at 11:59, Sakari Ailus <sakari.ailus@linux.intel.com> wrote:
>
> Hi Luis, Dave,
>
> On Thu, Apr 04, 2024 at 04:44:05PM -0600, Luigi311 wrote:
> > On 4/3/24 10:18, Sakari Ailus wrote:
> > > Hi Luis, Dave,
> > >
> > > On Wed, Apr 03, 2024 at 09:03:48AM -0600, git@luigi311.com wrote:
> > >> From: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > >>
> > >> Sony have advised that there are variants of the IMX258 sensor which
> > >> require slightly different register configuration to the mainline
> > >> imx258 driver defaults.
> > >>
> > >> There is no available run-time detection for the variant, so add
> > >> configuration via the DT compatible string.
> > >>
> > >> The Vision Components imx258 module supports PDAF, so add the
> > >> register differences for that variant
> > >>
> > >> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > >> Signed-off-by: Luis Garcia <git@luigi311.com>
> > >> ---
> > >>  drivers/media/i2c/imx258.c | 48 ++++++++++++++++++++++++++++++++++----
> > >>  1 file changed, 44 insertions(+), 4 deletions(-)
> > >>
> > >> diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
> > >> index 775d957c9b87..fa48da212037 100644
> > >> --- a/drivers/media/i2c/imx258.c
> > >> +++ b/drivers/media/i2c/imx258.c
> > >> @@ -6,6 +6,7 @@
> > >>  #include <linux/delay.h>
> > >>  #include <linux/i2c.h>
> > >>  #include <linux/module.h>
> > >> +#include <linux/of_device.h>
> > >>  #include <linux/pm_runtime.h>
> > >>  #include <linux/regulator/consumer.h>
> > >>  #include <media/v4l2-ctrls.h>
> > >> @@ -321,8 +322,6 @@ static const struct imx258_reg mipi_642mbps_24mhz_4l[] = {
> > >>
> > >>  static const struct imx258_reg mode_common_regs[] = {
> > >>    { 0x3051, 0x00 },
> > >> -  { 0x3052, 0x00 },
> > >> -  { 0x4E21, 0x14 },
> > >>    { 0x6B11, 0xCF },
> > >>    { 0x7FF0, 0x08 },
> > >>    { 0x7FF1, 0x0F },
> > >> @@ -345,7 +344,6 @@ static const struct imx258_reg mode_common_regs[] = {
> > >>    { 0x7FA8, 0x03 },
> > >>    { 0x7FA9, 0xFE },
> > >>    { 0x7B24, 0x81 },
> > >> -  { 0x7B25, 0x00 },
> > >>    { 0x6564, 0x07 },
> > >>    { 0x6B0D, 0x41 },
> > >>    { 0x653D, 0x04 },
> > >> @@ -460,6 +458,33 @@ static const struct imx258_reg mode_1048_780_regs[] = {
> > >>    { 0x034F, 0x0C },
> > >>  };
> > >>
> > >> +struct imx258_variant_cfg {
> > >> +  const struct imx258_reg *regs;
> > >> +  unsigned int num_regs;
> > >> +};
> > >> +
> > >> +static const struct imx258_reg imx258_cfg_regs[] = {
> > >> +  { 0x3052, 0x00 },
> > >> +  { 0x4E21, 0x14 },
> > >> +  { 0x7B25, 0x00 },
> > >> +};
> > >> +
> > >> +static const struct imx258_variant_cfg imx258_cfg = {
> > >> +  .regs = imx258_cfg_regs,
> > >> +  .num_regs = ARRAY_SIZE(imx258_cfg_regs),
> > >> +};
> > >> +
> > >> +static const struct imx258_reg imx258_pdaf_cfg_regs[] = {
> > >> +  { 0x3052, 0x01 },
> > >> +  { 0x4E21, 0x10 },
> > >> +  { 0x7B25, 0x01 },
> > >> +};
> > >> +
> > >> +static const struct imx258_variant_cfg imx258_pdaf_cfg = {
> > >> +  .regs = imx258_pdaf_cfg_regs,
> > >> +  .num_regs = ARRAY_SIZE(imx258_pdaf_cfg_regs),
> > >> +};
> > >> +
> > >>  static const char * const imx258_test_pattern_menu[] = {
> > >>    "Disabled",
> > >>    "Solid Colour",
> > >> @@ -637,6 +662,8 @@ struct imx258 {
> > >>    struct v4l2_subdev sd;
> > >>    struct media_pad pad;
> > >>
> > >> +  const struct imx258_variant_cfg *variant_cfg;
> > >> +
> > >>    struct v4l2_ctrl_handler ctrl_handler;
> > >>    /* V4L2 Controls */
> > >>    struct v4l2_ctrl *link_freq;
> > >> @@ -1104,6 +1131,14 @@ static int imx258_start_streaming(struct imx258 *imx258)
> > >>            return ret;
> > >>    }
> > >>
> > >> +  ret = imx258_write_regs(imx258, imx258->variant_cfg->regs,
> > >> +                          imx258->variant_cfg->num_regs);
> > >> +  if (ret) {
> > >> +          dev_err(&client->dev, "%s failed to set variant config\n",
> > >> +                  __func__);
> > >> +          return ret;
> > >> +  }
> > >> +
> > >>    ret = imx258_write_reg(imx258, IMX258_CLK_BLANK_STOP,
> > >>                           IMX258_REG_VALUE_08BIT,
> > >>                           imx258->csi2_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK ?
> > >> @@ -1492,6 +1527,10 @@ static int imx258_probe(struct i2c_client *client)
> > >>
> > >>    imx258->csi2_flags = ep.bus.mipi_csi2.flags;
> > >>
> > >> +  imx258->variant_cfg = of_device_get_match_data(&client->dev);
> > >
> > > You'll also need to keep this working for ACPI based systems. I.e. in
> > > practice remove "of_" prefix here and add the non-PDAF variant data to the
> > > relevant ACPI ID list.
> > >
> >
> > Removing of_ is easy enough and looking at all the other commits that make
> > this change in other drivers I dont see anything else being done besides
> > adding in the .data section that is down below for both imx258 and pdaf
> > versions. Is that what you are referencing or is there some other place
> > to add variant data to ACPI ID list?
>
> Speaking of which---are you absolutely certain there are two variants of
> this sensor? Many sensors that have a different pixel pattern (PDAF pixels
> or a non-Bayer pattern) can produce Bayer data when condigured so. The fact
> that you have differing register configuration for the PDAF and non-PDAF
> cases suggests this may well be the case.

I had a discussion with our contact at Sony over the configuration,
and Soho Enterprises who made the module I have also consulted with
Sony (their main person is ex Sony himself).

There is a spec version field in the OTP which reflects the pixel
pattern. It has defined options of:
- HDR pattern
- Binning pattern
- mono
- non-PDAF
- HDR HDD

Sony can't release information on how to read that information from
the sensor OTP as it is contractually locked by contracts with Intel.
Whilst information obtained via other routes means I have checked it
on my module as HDR pattern whilst the Nautilus platform has the
non-PDAF variant, I'm not going to spoil our relationship with Sony by
releasing that.

It's possible that the Nautilus sensor will work happily with the
settings required for the PDAF variant, but I have no way of testing
that, and the registers in question are undocumented. Changing them
blindly isn't going to make any friends, and I doubt existing platform
users wish to rerun all their image quality tests on the sensor to
validate the change.

Unless Intel wish to release the information on reading the OTP, we
have no way of telling the variants apart but need different register
configurations. If there is a better way of handling that situation
than compatible strings, then I'm open to suggestions.

There's a short thread on libcamera-devel from back in 2022 where I
was looking into this [1]

  Dave

[1] https://lists.libcamera.org/pipermail/libcamera-devel/2022-June/031449.html

> >
> > >> +  if (!imx258->variant_cfg)
> > >> +          imx258->variant_cfg = &imx258_cfg;
> > >> +
> > >>    /* Initialize subdev */
> > >>    v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
> > >>
> > >> @@ -1579,7 +1618,8 @@ MODULE_DEVICE_TABLE(acpi, imx258_acpi_ids);
> > >>  #endif
> > >>
> > >>  static const struct of_device_id imx258_dt_ids[] = {
> > >> -  { .compatible = "sony,imx258" },
> > >> +  { .compatible = "sony,imx258", .data = &imx258_cfg },
> > >> +  { .compatible = "sony,imx258-pdaf", .data = &imx258_pdaf_cfg },
> > >>    { /* sentinel */ }
> > >>  };
> > >>  MODULE_DEVICE_TABLE(of, imx258_dt_ids);
> > >
> >
>
> --
> Regards,
>
> Sakari Ailus

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [RFC 4/8] arm64/sysreg: Update ID_AA64MMFR0_EL1 register
From: Mark Brown @ 2024-04-05 13:16 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: linux-arm-kernel, Jonathan Corbet, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Catalin Marinas, Will Deacon,
	Mark Rutland, kvmarm, linux-kernel
In-Reply-To: <20240405080008.1225223-5-anshuman.khandual@arm.com>


[-- Attachment #1.1: Type: text/plain, Size: 270 bytes --]

On Fri, Apr 05, 2024 at 01:30:04PM +0530, Anshuman Khandual wrote:
> This updates ID_AA64MMFR0_EL1.FGT and ID_AA64MMFR0_EL1.PARANGE register
> fields as per the definitions based on DDI0601 2023-12.

Reviewed-by: Mark Brown <broonie@kernel.org>

against DDI0601 2024-03

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [RFC 3/8] arm64/sysreg: Add register fields for HDFGWTR2_EL2
From: Mark Brown @ 2024-04-05 13:08 UTC (permalink / raw)
  To: Anshuman Khandual
  Cc: linux-arm-kernel, Jonathan Corbet, Marc Zyngier, Oliver Upton,
	James Morse, Suzuki K Poulose, Catalin Marinas, Will Deacon,
	Mark Rutland, kvmarm, linux-kernel
In-Reply-To: <20240405080008.1225223-4-anshuman.khandual@arm.com>


[-- Attachment #1.1: Type: text/plain, Size: 234 bytes --]

On Fri, Apr 05, 2024 at 01:30:03PM +0530, Anshuman Khandual wrote:
> This adds register fields for HDFGWTR2_EL2 as per the definitions based
> on DDI0601 2023-12.

Reviewed-by: Mark Brown <broonie@kernel.org>

aginst DDT0601 2024-03.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox