* Re: [PATCH 5/7] arm64: dts: qcom: kaanapali: Add label properties to CoreSight devices
From: Konrad Dybcio @ 2026-04-14 10:15 UTC (permalink / raw)
To: Jie Gan, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20260410-add-label-to-coresight-device-v1-5-d71a6759dbc2@oss.qualcomm.com>
On 4/10/26 5:08 AM, Jie Gan wrote:
> Add label properties to TPDM nodes in the kaanapali device tree to
> provide human-readable identifiers for each CoreSight device. These
> labels allow userspace tools and the CoreSight framework to identify
> devices by name rather than by base address.
>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH v2 2/2] media: i2c: add os02g10 image sensor driver
From: Laurent Pinchart @ 2026-04-14 10:12 UTC (permalink / raw)
To: sakari.ailus@linux.intel.com
Cc: Elgin Perumbilly, Tarang Raval, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Hans de Goede, Vladimir Zapolskiy, Mehdi Djait, Benjamin Mugnier,
Sylvain Petinot, Hardevsinh Palaniya, Jingjing Xiong,
linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <ad4RrbNLa1EXYZM0@kekkonen.localdomain>
On Tue, Apr 14, 2026 at 01:06:37PM +0300, Sakari Ailus wrote:
> On Tue, Apr 14, 2026 at 12:57:27PM +0300, Laurent Pinchart wrote:
> > On Tue, Apr 14, 2026 at 09:43:32AM +0000, Elgin Perumbilly wrote:
> > > Hi Laurent,
> > >
> > > > I sent a review comment on v1.
> > > >
> > > > On Tue, Apr 14, 2026 at 02:19:45PM +0530, Elgin Perumbilly wrote:
> > > > > Add a v4l2 subdevice driver for the Omnivision os02g10 sensor.
> > > > >
> > > > > The Omnivision os02g10 is a CMOS image sensor with an active array size of
> > > > > 1920 x 1080.
> > > > >
> > > > > The following features are supported:
> > > > > - Manual exposure an gain control support
> > > > > - vblank/hblank control support
> > > > > - vflip/hflip control support
> > > > > - Test pattern control support
> > > > > - Supported resolution: 1920 x 1080 @ 30fps (SBGGR10)
> > > > >
> > > > > Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> > > > > Reviewed-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > > > > ---
> > > > > MAINTAINERS | 1 +
> > > > > drivers/media/i2c/Kconfig | 10 +
> > > > > drivers/media/i2c/Makefile | 1 +
> > > > > drivers/media/i2c/os02g10.c | 1039 +++++++++++++++++++++++++++++++++++
> > > > > 4 files changed, 1051 insertions(+)
> > > > > create mode 100644 drivers/media/i2c/os02g10.c
> > >
> > > I have added a new function, os02g10_set_framefmt, which dynamically sets
> > > the mode register.
> > >
> > > Please let me know if I have missed anything or if further changes are
> > > needed.
> >
> > You also need to drop the supported_modes array, and implement support
> > for .set_selection().
>
> I don't think we have a very well established behaviour for set_selections
> on sensors before the common raw sensor model, do we? I guess it can be the
> same as get_selections, though.
>
> Hopefully we can merge the metadata series soon...
I've bumped that high on my list of priority tasks.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH 4/7] arm64: dts: qcom: kodiak: Add label properties to CoreSight devices
From: Konrad Dybcio @ 2026-04-14 10:11 UTC (permalink / raw)
To: Jie Gan, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20260410-add-label-to-coresight-device-v1-4-d71a6759dbc2@oss.qualcomm.com>
On 4/10/26 5:08 AM, Jie Gan wrote:
> Add label properties to TPDM and CTI nodes in the kodiak device tree to
> provide human-readable identifiers for each CoreSight device. These
> labels allow userspace tools and the CoreSight framework to identify
> devices by name rather than by base address.
>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH 3/7] arm64: dts: qcom: monaco: Add label properties to CoreSight devices
From: Konrad Dybcio @ 2026-04-14 10:09 UTC (permalink / raw)
To: Jie Gan, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20260410-add-label-to-coresight-device-v1-3-d71a6759dbc2@oss.qualcomm.com>
On 4/10/26 5:08 AM, Jie Gan wrote:
> Add label properties to TPDM and CTI nodes in the monaco device tree to
> provide human-readable identifiers for each CoreSight device. These
> labels allow userspace tools and the CoreSight framework to identify
> devices by name rather than by base address.
>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH v3] dt-bindings: display: ti, am65x-dss: Fix AM62L DSS reg and clock constraints
From: Swamil Jain @ 2026-04-14 10:06 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: jyri.sarha, tomi.valkeinen, maarten.lankhorst, mripard,
tzimmermann, airlied, simona, robh, krzk+dt, conor+dt, devarsht,
dri-devel, devicetree, linux-kernel, praneeth, vigneshr
In-Reply-To: <20260411-resilient-tireless-centipede-cd6fef@quoll>
Hi Krzysztof,
On 4/11/26 19:37, Krzysztof Kozlowski wrote:
> On Fri, Apr 10, 2026 at 04:29:55PM +0530, Swamil Jain wrote:
>> clocks:
>> + minItems: 2
>> items:
>> - description: fck DSS functional clock
>> - description: vp1 Video Port 1 pixel clock
>> - description: vp2 Video Port 2 pixel clock
>>
>> clock-names:
>> + minItems: 2
>> items:
>> - const: fck
>> - const: vp1
>> @@ -179,6 +195,20 @@ allOf:
>> ports:
>> properties:
>> port@1: false
>> + clock-names:
>> + maxItems: 2
>> + clocks:
>> + maxItems: 2
>> + reg:
>> + maxItems: 5
>
> Also constrain for reg-names,
>
Sure, will add in v4.
>> + else:
>> + properties:
>> + clock-names:
>> + minItems: 3
>> + clocks:
>> + minItems: 3
>> + reg:
>> + minItems: 8
>
> Same here, please.
>
> And if you are sending new version: they should be listed in the same
> order as in top-level properties, so reg, reg-names, clocks and
> clock-names. (juging by the diff)
Yeah, sure, will keep the order. Thanks for the feedback, will
re-spin the patch.
Regards,
Swamil.
>
> Best regards,
> Krzysztof
>
^ permalink raw reply
* Re: [PATCH v2 2/2] media: i2c: add os02g10 image sensor driver
From: sakari.ailus @ 2026-04-14 10:06 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Elgin Perumbilly, Tarang Raval, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Hans de Goede, Vladimir Zapolskiy, Mehdi Djait, Benjamin Mugnier,
Sylvain Petinot, Hardevsinh Palaniya, Jingjing Xiong,
linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260414095727.GF4061@killaraus.ideasonboard.com>
Hi Laurent,
On Tue, Apr 14, 2026 at 12:57:27PM +0300, Laurent Pinchart wrote:
> On Tue, Apr 14, 2026 at 09:43:32AM +0000, Elgin Perumbilly wrote:
> > Hi Laurent,
> >
> > > I sent a review comment on v1.
> > >
> > > On Tue, Apr 14, 2026 at 02:19:45PM +0530, Elgin Perumbilly wrote:
> > > > Add a v4l2 subdevice driver for the Omnivision os02g10 sensor.
> > > >
> > > > The Omnivision os02g10 is a CMOS image sensor with an active array size of
> > > > 1920 x 1080.
> > > >
> > > > The following features are supported:
> > > > - Manual exposure an gain control support
> > > > - vblank/hblank control support
> > > > - vflip/hflip control support
> > > > - Test pattern control support
> > > > - Supported resolution: 1920 x 1080 @ 30fps (SBGGR10)
> > > >
> > > > Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> > > > Reviewed-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > > > ---
> > > > MAINTAINERS | 1 +
> > > > drivers/media/i2c/Kconfig | 10 +
> > > > drivers/media/i2c/Makefile | 1 +
> > > > drivers/media/i2c/os02g10.c | 1039 +++++++++++++++++++++++++++++++++++
> > > > 4 files changed, 1051 insertions(+)
> > > > create mode 100644 drivers/media/i2c/os02g10.c
> >
> > I have added a new function, os02g10_set_framefmt, which dynamically sets
> > the mode register.
> >
> > Please let me know if I have missed anything or if further changes are
> > needed.
>
> You also need to drop the supported_modes array, and implement support
> for .set_selection().
I don't think we have a very well established behaviour for set_selections
on sensors before the common raw sensor model, do we? I guess it can be the
same as get_selections, though.
Hopefully we can merge the metadata series soon...
--
Regards,
Sakari Ailus
^ permalink raw reply
* Re: [PATCH 2/7] arm64: dts: qcom: talos: Add label properties to CoreSight devices
From: Konrad Dybcio @ 2026-04-14 10:04 UTC (permalink / raw)
To: Jie Gan, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20260410-add-label-to-coresight-device-v1-2-d71a6759dbc2@oss.qualcomm.com>
On 4/10/26 5:08 AM, Jie Gan wrote:
> Add label properties to CTI and TPDM nodes in the talos device tree to
> provide human-readable identifiers for each CoreSight device. These
> labels allow userspace tools and the CoreSight framework to identify
> devices by name rather than by base address.
>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad3597,6 +3652,7 @@ tpdm@78b0000 {>
> clocks = <&aoss_qmp>;
> clock-names = "apb_pclk";
> + label = "tpdm_llm_gold";
>
> qcom,cmb-element-bits = <32>;
> qcom,cmb-msrs-num = <32>;
> @@ -3664,6 +3720,7 @@ cti@78e0000 {
>
> clocks = <&aoss_qmp>;
> clock-names = "apb_pclk";
> + label = "cti_apss";
> };
>
> cti@78f0000 {
> @@ -3672,6 +3729,7 @@ cti@78f0000 {
>
> clocks = <&aoss_qmp>;
> clock-names = "apb_pclk";
> + label = "cti_apss_1";
> };
>
> cti@7900000 {
> @@ -3680,6 +3738,7 @@ cti@7900000 {
>
> clocks = <&aoss_qmp>;
> clock-names = "apb_pclk";
> + label = "cti_apss_2";
> };
>
> remoteproc_cdsp: remoteproc@8300000 {
>
^ permalink raw reply
* Re: [PATCH 1/7] arm64: dts: qcom: lemans: Add label properties to CoreSight devices
From: Konrad Dybcio @ 2026-04-14 9:59 UTC (permalink / raw)
To: Jie Gan, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Tingwei Zhang
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20260410-add-label-to-coresight-device-v1-1-d71a6759dbc2@oss.qualcomm.com>
On 4/10/26 5:08 AM, Jie Gan wrote:
> Add label properties to TPDM and CTI nodes in the lemans device tree to
> provide human-readable identifiers for each CoreSight device. These
> labels allow userspace tools and the CoreSight framework to identify
> devices by name rather than by base address.
>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH v2 2/2] media: i2c: add os02g10 image sensor driver
From: Laurent Pinchart @ 2026-04-14 9:57 UTC (permalink / raw)
To: Elgin Perumbilly
Cc: sakari.ailus@linux.intel.com, Tarang Raval, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Hans de Goede, Vladimir Zapolskiy, Mehdi Djait, Benjamin Mugnier,
Sylvain Petinot, Hardevsinh Palaniya, Jingjing Xiong,
linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <MA0P287MB2178FAA81D07B561FA68014988252@MA0P287MB2178.INDP287.PROD.OUTLOOK.COM>
On Tue, Apr 14, 2026 at 09:43:32AM +0000, Elgin Perumbilly wrote:
> Hi Laurent,
>
> > I sent a review comment on v1.
> >
> > On Tue, Apr 14, 2026 at 02:19:45PM +0530, Elgin Perumbilly wrote:
> > > Add a v4l2 subdevice driver for the Omnivision os02g10 sensor.
> > >
> > > The Omnivision os02g10 is a CMOS image sensor with an active array size of
> > > 1920 x 1080.
> > >
> > > The following features are supported:
> > > - Manual exposure an gain control support
> > > - vblank/hblank control support
> > > - vflip/hflip control support
> > > - Test pattern control support
> > > - Supported resolution: 1920 x 1080 @ 30fps (SBGGR10)
> > >
> > > Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> > > Reviewed-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > > ---
> > > MAINTAINERS | 1 +
> > > drivers/media/i2c/Kconfig | 10 +
> > > drivers/media/i2c/Makefile | 1 +
> > > drivers/media/i2c/os02g10.c | 1039 +++++++++++++++++++++++++++++++++++
> > > 4 files changed, 1051 insertions(+)
> > > create mode 100644 drivers/media/i2c/os02g10.c
>
> I have added a new function, os02g10_set_framefmt, which dynamically sets
> the mode register.
>
> Please let me know if I have missed anything or if further changes are
> needed.
You also need to drop the supported_modes array, and implement support
for .set_selection().
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH v2 2/2] media: i2c: add os02g10 image sensor driver
From: Sakari Ailus @ 2026-04-14 9:57 UTC (permalink / raw)
To: Elgin Perumbilly
Cc: tarang.raval, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Hans Verkuil, Hans de Goede,
Vladimir Zapolskiy, Mehdi Djait, Laurent Pinchart,
Benjamin Mugnier, Sylvain Petinot, Hardevsinh Palaniya,
Jingjing Xiong, linux-media, devicetree, linux-kernel
In-Reply-To: <20260414084952.217215-3-elgin.perumbilly@siliconsignals.io>
Hi Elgin,
Thanks for the update.
On Tue, Apr 14, 2026 at 02:19:45PM +0530, Elgin Perumbilly wrote:
> Add a v4l2 subdevice driver for the Omnivision os02g10 sensor.
>
> The Omnivision os02g10 is a CMOS image sensor with an active array size of
> 1920 x 1080.
>
> The following features are supported:
> - Manual exposure an gain control support
> - vblank/hblank control support
> - vflip/hflip control support
> - Test pattern control support
> - Supported resolution: 1920 x 1080 @ 30fps (SBGGR10)
>
> Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> Reviewed-by: Tarang Raval <tarang.raval@siliconsignals.io>
> ---
> MAINTAINERS | 1 +
> drivers/media/i2c/Kconfig | 10 +
> drivers/media/i2c/Makefile | 1 +
> drivers/media/i2c/os02g10.c | 1039 +++++++++++++++++++++++++++++++++++
> 4 files changed, 1051 insertions(+)
> create mode 100644 drivers/media/i2c/os02g10.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 13409c71a765..28827e77ea31 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -19463,6 +19463,7 @@ M: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> L: linux-media@vger.kernel.org
> S: Maintained
> F: Documentation/devicetree/bindings/media/i2c/ovti,os02g10.yaml
> +F: drivers/media/i2c/os02g10.c
>
> OMNIVISION OS05B10 SENSOR DRIVER
> M: Himanshu Bhavani <himanshu.bhavani@siliconsignals.io>
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 5eb1e0e0a87a..dd6e9562acf6 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -372,6 +372,16 @@ config VIDEO_OG0VE1B
> To compile this driver as a module, choose M here: the
> module will be called og0ve1b.
>
> +config VIDEO_OS02G10
> + tristate "OmniVision OS02G10 sensor support"
> + select V4L2_CCI_I2C
> + help
> + This is a Video4Linux2 sensor driver for Omnivision
> + OS02G10 camera sensor.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called os02g10.
> +
> config VIDEO_OS05B10
> tristate "OmniVision OS05B10 sensor support"
> select V4L2_CCI_I2C
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index a3a6396df3c4..a7554d2eb140 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -84,6 +84,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
> obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o
> obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o
> obj-$(CONFIG_VIDEO_OG0VE1B) += og0ve1b.o
> +obj-$(CONFIG_VIDEO_OS02G10) += os02g10.o
> obj-$(CONFIG_VIDEO_OS05B10) += os05b10.o
> obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o
> obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
> diff --git a/drivers/media/i2c/os02g10.c b/drivers/media/i2c/os02g10.c
> new file mode 100644
> index 000000000000..b8df79162f88
> --- /dev/null
> +++ b/drivers/media/i2c/os02g10.c
> @@ -0,0 +1,1039 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * V4L2 Support for the OS02G10
> + *
> + * Copyright (C) 2026 Silicon Signals Pvt. Ltd.
> + *
> + */
> +
> +#include <linux/array_size.h>
> +#include <linux/bitops.h>
> +#include <linux/cleanup.h>
> +#include <linux/clk.h>
> +#include <linux/container_of.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/property.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/units.h>
> +#include <linux/types.h>
> +#include <linux/time.h>
> +#include <linux/regmap.h>
> +
> +#include <media/v4l2-cci.h>
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-mediabus.h>
> +
> +#define OS02G10_XCLK_FREQ (24 * HZ_PER_MHZ)
> +
> +/* Add page number in CCI private bits [31:28] of the register address */
> +#define OS02G10_PAGE_REG8(p, x) (((p) << CCI_REG_PRIVATE_SHIFT) | CCI_REG8(x))
> +#define OS02G10_PAGE_REG16(p, x) (((p) << CCI_REG_PRIVATE_SHIFT) | CCI_REG16(x))
> +#define OS02G10_PAGE_REG24(p, x) (((p) << CCI_REG_PRIVATE_SHIFT) | CCI_REG24(x))
I just noticed regmap supports paging through register ranges. Could this
work for the driver as-is?
> +
> +#define OS02G10_REG_PAGE_SELECT CCI_REG8(0xfd)
> +
> +/* Page 0 */
> +#define OS02G10_REG_CHIPID OS02G10_PAGE_REG24(0x00, 0x02)
> +#define OS02G10_CHIPID 0x560247
> +
> +#define OS02G10_REG_PLL_DIV_CTRL OS02G10_PAGE_REG8(0x00, 0x30)
> +#define OS02G10_REG_PLL_DCTL_BIAS_CTRL OS02G10_PAGE_REG8(0x00, 0x35)
> +#define OS02G10_REG_GATE_EN_CTRL OS02G10_PAGE_REG8(0x00, 0x38)
> +#define OS02G10_REG_DPLL_NC OS02G10_PAGE_REG8(0x00, 0x41)
> +#define OS02G10_REG_MP_PHASE_CTRL OS02G10_PAGE_REG8(0x00, 0x44)
> +
> +/* Page 1 */
> +#define OS02G10_REG_STREAM_CTRL OS02G10_PAGE_REG8(0x01, 0xb1)
> +#define OS02G10_STREAM_CTRL_ON 0x03
> +#define OS02G10_STREAM_CTRL_OFF 0x00
> +
> +#define OS02G10_REG_FRAME_SYNC OS02G10_PAGE_REG8(0x01, 0x01)
> +
> +#define OS02G10_REG_FRAME_LENGTH OS02G10_PAGE_REG16(0x01, 0x0e)
> +#define OS02G10_FRAME_LENGTH_MAX 0xffff
> +#define OS02G10_REG_HBLANK OS02G10_PAGE_REG16(0x01, 0x09)
> +
> +#define OS02G10_REG_FRAME_TEST_CTRL OS02G10_PAGE_REG8(0x01, 0x0d)
> +#define OS02G10_FRAME_EXP_SEPERATE_EN BIT(4)
> +#define OS02G10_TEST_PATTERN_ENABLE BIT(0)
> +
> +#define OS02G10_REG_ULP_PWD_DUMMY_CTRL OS02G10_PAGE_REG8(0x01, 0x3c)
> +#define OS02G10_REG_DC_LEVEL_LIMIT_EN OS02G10_PAGE_REG8(0x01, 0x46)
> +#define OS02G10_REG_DC_LEVEL_LIMIT_L OS02G10_PAGE_REG8(0x01, 0x47)
> +#define OS02G10_REG_BLC_DATA_LIMIT_L OS02G10_PAGE_REG8(0x01, 0x48)
> +#define OS02G10_REG_DC_BLC_LIMIT_H OS02G10_PAGE_REG8(0x01, 0x49)
> +
> +#define OS02G10_REG_HS_LP_CTRL OS02G10_PAGE_REG8(0x01, 0x92)
> +#define OS02G10_REG_HS_LEVEL OS02G10_PAGE_REG8(0x01, 0x9d)
> +#define OS02G10_REG_HS_DRV OS02G10_PAGE_REG8(0x01, 0x9e)
> +
> +#define OS02G10_REG_GB_SUBOFFSET OS02G10_PAGE_REG8(0x01, 0xf0)
> +#define OS02G10_REG_BLUE_SUBOFFSET OS02G10_PAGE_REG8(0x01, 0xf1)
> +#define OS02G10_REG_RED_SUBOFFSET OS02G10_PAGE_REG8(0x01, 0xf2)
> +#define OS02G10_REG_GR_SUBOFFSET OS02G10_PAGE_REG8(0x01, 0xf3)
> +
> +#define OS02G10_REG_ABL_TRIGGER OS02G10_PAGE_REG8(0x01, 0xfa)
> +#define OS02G10_REG_ABL OS02G10_PAGE_REG8(0x01, 0xfb)
> +
> +#define OS02G10_REG_H_SIZE_MIPI OS02G10_PAGE_REG16(0x01, 0x8e)
> +#define OS02G10_REG_V_SIZE_MIPI OS02G10_PAGE_REG16(0x01, 0x90)
> +#define OS02G10_REG_MIPI_TX_SPEED_CTRL OS02G10_PAGE_REG8(0x01, 0xa1)
> +
> +#define OS02G10_REG_LONG_EXPOSURE OS02G10_PAGE_REG16(0x01, 0x03)
> +#define OS02G10_EXPOSURE_MIN 4
> +#define OS02G10_EXPOSURE_STEP 1
> +#define OS02G10_EXPOSURE_MARGIN 9
> +
> +#define OS02G10_REG_ANALOG_GAIN OS02G10_PAGE_REG8(0x01, 0x24)
> +#define OS02G10_ANALOG_GAIN_MIN 0x10
> +#define OS02G10_ANALOG_GAIN_MAX 0xf8
> +#define OS02G10_ANALOG_GAIN_STEP 1
> +#define OS02G10_ANALOG_GAIN_DEFAULT 0x10
> +
> +#define OS02G10_REG_DIGITAL_GAIN_H OS02G10_PAGE_REG8(0x01, 0x37)
> +#define OS02G10_REG_DIGITAL_GAIN_L OS02G10_PAGE_REG8(0x01, 0x39)
> +#define OS02G10_DIGITAL_GAIN_MIN 0x40
> +#define OS02G10_DIGITAL_GAIN_MAX 0x800
> +#define OS02G10_DIGITAL_GAIN_STEP 64
> +#define OS02G10_DIGITAL_GAIN_DEFAULT 0x40
> +
> +#define OS02G10_REG_FLIP_MIRROR OS02G10_PAGE_REG8(0x01, 0x3f)
> +#define OS02G10_FLIP BIT(1)
> +#define OS02G10_MIRROR BIT(0)
> +
> +/* Page 2 */
> +#define OS02G10_REG_V_START OS02G10_PAGE_REG16(0x02, 0xa0)
> +#define OS02G10_REG_V_SIZE OS02G10_PAGE_REG16(0x02, 0xa2)
> +#define OS02G10_REG_H_START OS02G10_PAGE_REG16(0x02, 0xa4)
> +#define OS02G10_REG_H_SIZE OS02G10_PAGE_REG16(0x02, 0xa6)
> +
> +#define OS02G10_REG_SIF_CTRL OS02G10_PAGE_REG8(0x02, 0x5e)
> +#define OS02G10_ORIENTATION_BAYER_FIX 0x32
> +
> +#define OS02G10_LINK_FREQ_720MHZ (720 * HZ_PER_MHZ)
> +
> +/* OS02G10 native and active pixel array size */
> +static const struct v4l2_rect os02g10_native_area = {
> + .top = 0,
> + .left = 0,
> + .width = 1928,
> + .height = 1088,
> +};
> +
> +static const struct v4l2_rect os02g10_active_area = {
> + .top = 4,
> + .left = 4,
> + .width = 1920,
> + .height = 1080,
> +};
> +
> +static const char * const os02g10_supply_name[] = {
> + "avdd", /* Analog power */
> + "dovdd", /* Digital I/O power */
> + "dvdd", /* Digital core power */
> +};
> +
> +struct os02g10 {
> + struct device *dev;
> + struct regmap *cci;
> + struct v4l2_subdev sd;
> + struct media_pad pad;
> + struct clk *xclk;
> + struct gpio_desc *reset_gpio;
> + struct regulator_bulk_data supplies[ARRAY_SIZE(os02g10_supply_name)];
> +
> + /* V4L2 Controls */
> + struct v4l2_ctrl_handler handler;
> + struct v4l2_ctrl *link_freq;
> + struct v4l2_ctrl *hblank;
> + struct v4l2_ctrl *vblank;
> + struct v4l2_ctrl *exposure;
> + struct v4l2_ctrl *vflip;
> + struct v4l2_ctrl *hflip;
> +
> + u32 link_freq_index;
> +
> + u8 current_page;
> + struct mutex page_lock;
> +};
> +
> +struct os02g10_mode {
> + u32 width;
> + u32 height;
> + u32 vts_def;
> + u32 hts_def;
> + u32 exp_def;
> + u32 x_start;
> + u32 y_start;
> +};
> +
> +static const struct cci_reg_sequence os02g10_common_regs[] = {
> + { OS02G10_REG_PLL_DIV_CTRL, 0x0a},
> + { OS02G10_REG_PLL_DCTL_BIAS_CTRL, 0x04},
> + { OS02G10_REG_GATE_EN_CTRL, 0x11},
> + { OS02G10_REG_DPLL_NC, 0x06},
> + { OS02G10_REG_MP_PHASE_CTRL, 0x20},
> + { OS02G10_PAGE_REG8(0x01, 0x19), 0x50},
> + { OS02G10_PAGE_REG8(0x01, 0x1a), 0x0c},
> + { OS02G10_PAGE_REG8(0x01, 0x1b), 0x0d},
> + { OS02G10_PAGE_REG8(0x01, 0x1c), 0x00},
> + { OS02G10_PAGE_REG8(0x01, 0x1d), 0x75},
> + { OS02G10_PAGE_REG8(0x01, 0x1e), 0x52},
> + { OS02G10_PAGE_REG8(0x01, 0x22), 0x14},
> + { OS02G10_PAGE_REG8(0x01, 0x25), 0x44},
> + { OS02G10_PAGE_REG8(0x01, 0x26), 0x0f},
> + { OS02G10_REG_ULP_PWD_DUMMY_CTRL, 0xca},
> + { OS02G10_PAGE_REG8(0x01, 0x3d), 0x4a},
> + { OS02G10_PAGE_REG8(0x01, 0x40), 0x0f},
> + { OS02G10_PAGE_REG8(0x01, 0x43), 0x38},
> + { OS02G10_REG_DC_LEVEL_LIMIT_EN, 0x01},
> + { OS02G10_REG_DC_LEVEL_LIMIT_L, 0x00},
> + { OS02G10_REG_DC_BLC_LIMIT_H, 0x32},
> + { OS02G10_PAGE_REG8(0x01, 0x50), 0x01},
> + { OS02G10_PAGE_REG8(0x01, 0x51), 0x28},
> + { OS02G10_PAGE_REG8(0x01, 0x52), 0x20},
> + { OS02G10_PAGE_REG8(0x01, 0x53), 0x03},
> + { OS02G10_PAGE_REG8(0x01, 0x57), 0x16},
> + { OS02G10_PAGE_REG8(0x01, 0x59), 0x01},
> + { OS02G10_PAGE_REG8(0x01, 0x5a), 0x01},
> + { OS02G10_PAGE_REG8(0x01, 0x5d), 0x04},
> + { OS02G10_PAGE_REG8(0x01, 0x6a), 0x04},
> + { OS02G10_PAGE_REG8(0x01, 0x6b), 0x03},
> + { OS02G10_PAGE_REG8(0x01, 0x6e), 0x28},
> + { OS02G10_PAGE_REG8(0x01, 0x71), 0xc2},
> + { OS02G10_PAGE_REG8(0x01, 0x72), 0x04},
> + { OS02G10_PAGE_REG8(0x01, 0x73), 0x38},
> + { OS02G10_PAGE_REG8(0x01, 0x74), 0x04},
> + { OS02G10_PAGE_REG8(0x01, 0x79), 0x00},
> + { OS02G10_PAGE_REG8(0x01, 0x7a), 0xb2},
> + { OS02G10_PAGE_REG8(0x01, 0x7b), 0x10},
> + { OS02G10_REG_HS_LP_CTRL, 0x02},
> + { OS02G10_REG_HS_LEVEL, 0x03},
> + { OS02G10_REG_HS_DRV, 0x55},
> + { OS02G10_PAGE_REG8(0x01, 0xb8), 0x70},
> + { OS02G10_PAGE_REG8(0x01, 0xb9), 0x70},
> + { OS02G10_PAGE_REG8(0x01, 0xba), 0x70},
> + { OS02G10_PAGE_REG8(0x01, 0xbb), 0x70},
> + { OS02G10_PAGE_REG8(0x01, 0xbc), 0x00},
> + { OS02G10_PAGE_REG8(0x01, 0xc4), 0x6d},
> + { OS02G10_PAGE_REG8(0x01, 0xc5), 0x6d},
> + { OS02G10_PAGE_REG8(0x01, 0xc6), 0x6d},
> + { OS02G10_PAGE_REG8(0x01, 0xc7), 0x6d},
> + { OS02G10_PAGE_REG8(0x01, 0xcc), 0x11},
> + { OS02G10_PAGE_REG8(0x01, 0xcd), 0xe0},
> + { OS02G10_PAGE_REG8(0x01, 0xd0), 0x1b},
> + { OS02G10_PAGE_REG8(0x01, 0xd2), 0x76},
> + { OS02G10_PAGE_REG8(0x01, 0xd3), 0x68},
> + { OS02G10_PAGE_REG8(0x01, 0xd4), 0x68},
> + { OS02G10_PAGE_REG8(0x01, 0xd5), 0x73},
> + { OS02G10_PAGE_REG8(0x01, 0xd6), 0x73},
> + { OS02G10_PAGE_REG8(0x01, 0xe8), 0x55},
> + { OS02G10_REG_GB_SUBOFFSET, 0x40},
> + { OS02G10_REG_BLUE_SUBOFFSET, 0x40},
> + { OS02G10_REG_RED_SUBOFFSET, 0x40},
> + { OS02G10_REG_GR_SUBOFFSET, 0x40},
> + { OS02G10_REG_ABL_TRIGGER, 0x1c},
> + { OS02G10_REG_ABL, 0x33},
> + { OS02G10_PAGE_REG8(0x01, 0xfc), 0x80},
> + { OS02G10_PAGE_REG8(0x01, 0xfe), 0x80},
> + { OS02G10_PAGE_REG8(0x03, 0x03), 0x67},
> + { OS02G10_PAGE_REG8(0x03, 0x00), 0x59},
> + { OS02G10_PAGE_REG8(0x03, 0x04), 0x11},
> + { OS02G10_PAGE_REG8(0x03, 0x05), 0x04},
> + { OS02G10_PAGE_REG8(0x03, 0x06), 0x0c},
> + { OS02G10_PAGE_REG8(0x03, 0x07), 0x08},
> + { OS02G10_PAGE_REG8(0x03, 0x08), 0x08},
> + { OS02G10_PAGE_REG8(0x03, 0x09), 0x4f},
> + { OS02G10_PAGE_REG8(0x03, 0x0b), 0x08},
> + { OS02G10_PAGE_REG8(0x03, 0x0d), 0x26},
> + { OS02G10_PAGE_REG8(0x03, 0x0f), 0x00},
> + { OS02G10_PAGE_REG8(0x02, 0x34), 0xfe},
> + { OS02G10_REG_MIPI_TX_SPEED_CTRL, 0x05},
> +};
> +
> +static const struct os02g10_mode supported_modes[] = {
> + {
> + .width = 1920,
> + .height = 1080,
> + .vts_def = 1246,
> + .hts_def = 1082,
> + .exp_def = 1100,
> + .x_start = 2,
> + .y_start = 6,
> + },
> +};
> +
> +static const s64 link_freq_menu_items[] = {
> + OS02G10_LINK_FREQ_720MHZ,
> +};
> +
> +static const char * const os02g10_test_pattern_menu[] = {
> + "Disabled",
> + "Colorbar",
> +};
> +
> +static int os02g10_page_access(struct os02g10 *os02g10, u32 reg, int *err)
> +{
> + u8 page = (reg & CCI_REG_PRIVATE_MASK) >> CCI_REG_PRIVATE_SHIFT;
> + int ret = 0;
> +
> + if (err && *err)
> + return *err;
> +
> + guard(mutex)(&os02g10->page_lock);
> +
> + /* Perform page access before read/write */
> + if (os02g10->current_page == page)
> + return ret;
> +
> + ret = cci_write(os02g10->cci, OS02G10_REG_PAGE_SELECT, page, err);
> + if (!ret)
> + os02g10->current_page = page;
> +
> + return ret;
> +}
> +
> +static int os02g10_read(struct os02g10 *os02g10, u32 reg, u64 *val, int *err)
> +{
> + u32 addr = reg & ~CCI_REG_PRIVATE_MASK;
> + int ret;
> +
> + ret = os02g10_page_access(os02g10, reg, err);
> + if (ret)
> + return ret;
> +
> + return cci_read(os02g10->cci, addr, val, err);
> +}
> +
> +static int os02g10_write(struct os02g10 *os02g10, u32 reg, u64 val, int *err)
> +{
> + u32 addr = reg & ~CCI_REG_PRIVATE_MASK;
> + int ret;
> +
> + ret = os02g10_page_access(os02g10, reg, err);
> + if (ret)
> + return ret;
> +
> + return cci_write(os02g10->cci, addr, val, err);
> +}
> +
> +static int os02g10_update_bits(struct os02g10 *os02g10, u32 reg, u64 mask,
> + u64 val, int *err)
> +{
> + u32 addr = reg & ~CCI_REG_PRIVATE_MASK;
> + int ret;
> +
> + ret = os02g10_page_access(os02g10, reg, err);
> + if (ret)
> + return ret;
> +
> + return cci_update_bits(os02g10->cci, addr, mask, val, err);
> +}
> +
> +static int os02g10_multi_reg_write(struct os02g10 *os02g10,
> + const struct cci_reg_sequence *regs,
> + unsigned int num_regs, int *err)
> +{
> + unsigned int i;
> + int ret;
> +
> + for (i = 0; i < num_regs; i++) {
> + ret = os02g10_write(os02g10, regs[i].reg, regs[i].val, err);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static inline struct os02g10 *to_os02g10(struct v4l2_subdev *_sd)
> +{
> + return container_of_const(_sd, struct os02g10, sd);
You can call "_sd" "sd".
> +}
> +
> +static u32 os02g10_get_format_code(struct os02g10 *os02g10)
> +{
> + static const u32 codes[2][2] = {
> + { MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SGBRG10_1X10, },
> + { MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SRGGB10_1X10, },
> + };
> +
Extra newline.
> + u32 code = codes[os02g10->vflip->val][os02g10->hflip->val];
> +
> + return code;
> +}
> +
> +static int os02g10_set_ctrl(struct v4l2_ctrl *ctrl)
> +{
> + struct os02g10 *os02g10 = container_of_const(ctrl->handler,
> + struct os02g10, handler);
> + struct v4l2_subdev_state *state;
> + struct v4l2_mbus_framefmt *fmt;
> + int ret = 0;
> +
> + state = v4l2_subdev_get_locked_active_state(&os02g10->sd);
> + fmt = v4l2_subdev_state_get_format(state, 0);
> +
> + if (ctrl->id == V4L2_CID_VBLANK) {
> + /* Honour the VBLANK limits when setting exposure */
> + s64 max = fmt->height + ctrl->val - OS02G10_EXPOSURE_MARGIN;
> +
> + ret = __v4l2_ctrl_modify_range(os02g10->exposure,
> + os02g10->exposure->minimum, max,
> + os02g10->exposure->step,
> + os02g10->exposure->default_value);
> + if (ret)
> + return ret;
> + }
> +
> + if (pm_runtime_get_if_active(os02g10->dev) == 0)
> + return 0;
> +
> + switch (ctrl->id) {
> + case V4L2_CID_EXPOSURE:
> + os02g10_write(os02g10, OS02G10_REG_LONG_EXPOSURE, ctrl->val, &ret);
> + break;
> + case V4L2_CID_ANALOGUE_GAIN:
> + os02g10_write(os02g10, OS02G10_REG_ANALOG_GAIN, ctrl->val, &ret);
> + break;
> + case V4L2_CID_DIGITAL_GAIN:
> + os02g10_write(os02g10, OS02G10_REG_DIGITAL_GAIN_L,
> + (ctrl->val & 0xff), &ret);
> + os02g10_write(os02g10, OS02G10_REG_DIGITAL_GAIN_H,
> + ((ctrl->val >> 8) & 0x7), &ret);
> + break;
> + case V4L2_CID_VBLANK:
> + u64 vts = ctrl->val + fmt->height;
> +
> + os02g10_update_bits(os02g10, OS02G10_REG_FRAME_TEST_CTRL,
> + OS02G10_FRAME_EXP_SEPERATE_EN,
> + OS02G10_FRAME_EXP_SEPERATE_EN, &ret);
> + os02g10_write(os02g10, OS02G10_REG_FRAME_LENGTH, vts, &ret);
> + break;
> + case V4L2_CID_HFLIP:
> + case V4L2_CID_VFLIP:
> + os02g10_write(os02g10, OS02G10_REG_FLIP_MIRROR,
> + os02g10->hflip->val | os02g10->vflip->val << 1,
> + &ret);
> + os02g10_write(os02g10, OS02G10_REG_SIF_CTRL,
> + OS02G10_ORIENTATION_BAYER_FIX, &ret);
> + break;
> + case V4L2_CID_TEST_PATTERN:
> + os02g10_update_bits(os02g10,
> + OS02G10_REG_FRAME_TEST_CTRL,
> + OS02G10_TEST_PATTERN_ENABLE,
> + ctrl->val ? OS02G10_TEST_PATTERN_ENABLE : 0,
> + &ret);
> + break;
> + default:
> + ret = -EINVAL;
> + break;
> + }
> + os02g10_write(os02g10, OS02G10_REG_FRAME_SYNC, 0x01, &ret);
> +
> + pm_runtime_put(os02g10->dev);
> +
> + return ret;
> +}
> +
> +static const struct v4l2_ctrl_ops os02g10_ctrl_ops = {
> + .s_ctrl = os02g10_set_ctrl,
> +};
> +
> +static int os02g10_init_controls(struct os02g10 *os02g10)
> +{
> + const struct os02g10_mode *mode = &supported_modes[0];
> + u64 vblank_def, hblank_def, exp_max, pixel_rate;
> + struct v4l2_fwnode_device_properties props;
> + struct v4l2_ctrl_handler *ctrl_hdlr;
> + int ret;
> +
> + ctrl_hdlr = &os02g10->handler;
> + v4l2_ctrl_handler_init(ctrl_hdlr, 12);
> +
> + /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
> + pixel_rate = div_u64(OS02G10_LINK_FREQ_720MHZ * 2 * 2, 10);
> + v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops, V4L2_CID_PIXEL_RATE, 0,
> + pixel_rate, 1, pixel_rate);
> +
> + os02g10->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_LINK_FREQ,
> + os02g10->link_freq_index,
> + 0, link_freq_menu_items);
> + if (os02g10->link_freq)
> + os02g10->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + /*
> + * Multiply by 2 to ensure positive hblank.
V4L2 controls can also have negative values, there's no need to multiply
line length in pixels for this reason.
> + * Datasheet does not provide information about the unit of HTS.
> + */
> + hblank_def = (mode->hts_def * 2) - mode->width;
> + os02g10->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_HBLANK, hblank_def, hblank_def,
> + 1, hblank_def);
> + if (os02g10->hblank)
> + os02g10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> +
> + vblank_def = mode->vts_def - mode->height;
> + os02g10->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_VBLANK, vblank_def,
> + OS02G10_FRAME_LENGTH_MAX - mode->height,
> + 1, vblank_def);
> +
> + exp_max = mode->vts_def - OS02G10_EXPOSURE_MARGIN;
> + os02g10->exposure =
> + v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_EXPOSURE,
> + OS02G10_EXPOSURE_MIN, exp_max,
> + OS02G10_EXPOSURE_STEP, mode->exp_def);
> +
> + v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_ANALOGUE_GAIN, OS02G10_ANALOG_GAIN_MIN,
> + OS02G10_ANALOG_GAIN_MAX, OS02G10_ANALOG_GAIN_STEP,
> + OS02G10_ANALOG_GAIN_DEFAULT);
> +
> + v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_DIGITAL_GAIN, OS02G10_DIGITAL_GAIN_MIN,
> + OS02G10_DIGITAL_GAIN_MAX, OS02G10_DIGITAL_GAIN_STEP,
> + OS02G10_DIGITAL_GAIN_DEFAULT);
> +
> + os02g10->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_HFLIP, 0, 1, 1, 0);
> + if (os02g10->hflip)
> + os02g10->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> +
> + os02g10->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_VFLIP, 0, 1, 1, 0);
> + if (os02g10->vflip)
> + os02g10->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> +
> + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &os02g10_ctrl_ops,
> + V4L2_CID_TEST_PATTERN,
> + ARRAY_SIZE(os02g10_test_pattern_menu) - 1,
> + 0, 0, os02g10_test_pattern_menu);
> + if (ctrl_hdlr->error) {
You can skip this error check; doing this after
v4l2_ctrl_new_fwnode_properties() is enough.
> + ret = ctrl_hdlr->error;
> + dev_err(os02g10->dev, "control init failed (%d)\n", ret);
> + goto err_handler_free;
> + }
> +
> + ret = v4l2_fwnode_device_parse(os02g10->dev, &props);
> + if (ret)
> + goto err_handler_free;
> +
> + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr,
> + &os02g10_ctrl_ops, &props);
> + if (ret)
> + goto err_handler_free;
> +
> + os02g10->sd.ctrl_handler = ctrl_hdlr;
> +
> + return 0;
> +
> +err_handler_free:
> + v4l2_ctrl_handler_free(ctrl_hdlr);
> +
> + return ret;
> +}
> +
> +static int os02g10_set_framefmt(struct os02g10 *os02g10,
> + struct v4l2_subdev_state *state)
> +{
> + const struct v4l2_mbus_framefmt *format;
> + const struct os02g10_mode *mode;
> + int ret = 0;
> +
> + format = v4l2_subdev_state_get_format(state, 0);
> + mode = v4l2_find_nearest_size(supported_modes,
> + ARRAY_SIZE(supported_modes), width,
> + height, format->width, format->height);
> +
> + os02g10_write(os02g10, OS02G10_REG_V_START, mode->y_start, &ret);
> + os02g10_write(os02g10, OS02G10_REG_V_SIZE, mode->height, &ret);
> + os02g10_write(os02g10, OS02G10_REG_V_SIZE_MIPI, mode->height, &ret);
> + os02g10_write(os02g10, OS02G10_REG_H_START, mode->x_start, &ret);
> + os02g10_write(os02g10, OS02G10_REG_H_SIZE, mode->width, &ret);
> + os02g10_write(os02g10, OS02G10_REG_H_SIZE_MIPI, mode->width, &ret);
> +
> + return ret;
> +}
> +
> +static int os02g10_enable_streams(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state, u32 pad,
> + u64 streams_mask)
> +{
> + struct os02g10 *os02g10 = to_os02g10(sd);
> + int ret;
> +
> + ret = pm_runtime_resume_and_get(os02g10->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = os02g10_multi_reg_write(os02g10, os02g10_common_regs,
> + ARRAY_SIZE(os02g10_common_regs), NULL);
> + if (ret) {
> + dev_err(os02g10->dev, "failed to write common registers\n");
> + goto err_rpm_put;
> + }
> +
> + ret = os02g10_set_framefmt(os02g10, state);
> + if (ret) {
> + dev_err(os02g10->dev, "failed to set frame foramt\n");
> + goto err_rpm_put;
> + }
> +
> + /* Apply customized values from user */
> + ret = __v4l2_ctrl_handler_setup(os02g10->sd.ctrl_handler);
> + if (ret)
> + goto err_rpm_put;
> +
> + ret = os02g10_write(os02g10, OS02G10_REG_STREAM_CTRL,
> + OS02G10_STREAM_CTRL_ON, NULL);
> + if (ret)
> + goto err_rpm_put;
> +
> + /* vflip and hflip cannot change during streaming */
> + __v4l2_ctrl_grab(os02g10->vflip, true);
> + __v4l2_ctrl_grab(os02g10->hflip, true);
> +
> + return 0;
> +
> +err_rpm_put:
> + pm_runtime_put(os02g10->dev);
> + return ret;
> +}
> +
> +static int os02g10_disable_streams(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state, u32 pad,
> + u64 streams_mask)
> +{
> + struct os02g10 *os02g10 = to_os02g10(sd);
> + int ret;
> +
> + ret = os02g10_write(os02g10, OS02G10_REG_STREAM_CTRL,
> + OS02G10_STREAM_CTRL_OFF, NULL);
> + if (ret)
> + dev_err(os02g10->dev, "Failed to stop stream\n");
> +
> + __v4l2_ctrl_grab(os02g10->vflip, false);
> + __v4l2_ctrl_grab(os02g10->hflip, false);
> +
> + pm_runtime_put(os02g10->dev);
> +
> + return ret;
> +}
> +
> +static int os02g10_get_selection(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_selection *sel)
> +{
> + switch (sel->target) {
> + case V4L2_SEL_TGT_CROP_BOUNDS:
> + case V4L2_SEL_TGT_NATIVE_SIZE:
> + sel->r = os02g10_native_area;
> + return 0;
> + case V4L2_SEL_TGT_CROP:
> + case V4L2_SEL_TGT_CROP_DEFAULT:
> + sel->r = os02g10_active_area;
> + return 0;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int os02g10_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_mbus_code_enum *code)
> +{
> + struct os02g10 *os02g10 = to_os02g10(sd);
> +
> + if (code->index)
> + return -EINVAL;
> +
> + code->code = os02g10_get_format_code(os02g10);
> +
> + return 0;
> +}
> +
> +static int os02g10_enum_frame_size(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_frame_size_enum *fse)
> +{
> + struct os02g10 *os02g10 = to_os02g10(sd);
> +
> + if (fse->index >= ARRAY_SIZE(supported_modes))
> + return -EINVAL;
> +
> + if (fse->code != os02g10_get_format_code(os02g10))
> + return -EINVAL;
> +
> + fse->min_width = supported_modes[fse->index].width;
> + fse->max_width = fse->min_width;
> + fse->min_height = supported_modes[fse->index].height;
> + fse->max_height = fse->min_height;
> +
> + return 0;
> +}
> +
> +static int os02g10_set_pad_format(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct os02g10 *os02g10 = to_os02g10(sd);
> + struct v4l2_mbus_framefmt *format;
> + const struct os02g10_mode *mode;
> + int ret;
> +
> + format = v4l2_subdev_state_get_format(sd_state, 0);
> +
> + mode = v4l2_find_nearest_size(supported_modes,
> + ARRAY_SIZE(supported_modes),
> + width, height,
> + fmt->format.width, fmt->format.height);
> +
> + fmt->format.code = os02g10_get_format_code(os02g10);
> + fmt->format.width = mode->width;
> + fmt->format.height = mode->height;
> + fmt->format.field = V4L2_FIELD_NONE;
> + fmt->format.colorspace = V4L2_COLORSPACE_RAW;
> + fmt->format.quantization = V4L2_QUANTIZATION_FULL_RANGE;
> + fmt->format.xfer_func = V4L2_XFER_FUNC_NONE;
> +
> + *format = fmt->format;
> +
> + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
> + u32 vblank_def = mode->vts_def - mode->height;
You can declare ret here.
> +
> + ret = __v4l2_ctrl_modify_range(os02g10->vblank, vblank_def,
> + OS02G10_FRAME_LENGTH_MAX -
> + mode->height, 1, vblank_def);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int os02g10_init_state(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state)
> +{
> + struct os02g10 *os02g10 = to_os02g10(sd);
> + struct v4l2_subdev_format fmt = {
> + .which = V4L2_SUBDEV_FORMAT_TRY,
> + .format = {
> + .code = os02g10_get_format_code(os02g10),
> + .width = supported_modes[0].width,
> + .height = supported_modes[0].height,
> + },
> + };
> +
> + os02g10_set_pad_format(sd, state, &fmt);
> +
> + return 0;
> +}
> +
> +static const struct v4l2_subdev_video_ops os02g10_video_ops = {
> + .s_stream = v4l2_subdev_s_stream_helper,
> +};
> +
> +static const struct v4l2_subdev_pad_ops os02g10_pad_ops = {
> + .enum_mbus_code = os02g10_enum_mbus_code,
> + .get_fmt = v4l2_subdev_get_fmt,
> + .set_fmt = os02g10_set_pad_format,
> + .get_selection = os02g10_get_selection,
> + .enum_frame_size = os02g10_enum_frame_size,
> + .enable_streams = os02g10_enable_streams,
> + .disable_streams = os02g10_disable_streams,
> +};
> +
> +static const struct v4l2_subdev_ops os02g10_subdev_ops = {
> + .video = &os02g10_video_ops,
> + .pad = &os02g10_pad_ops,
> +};
> +
> +static const struct v4l2_subdev_internal_ops os02g10_internal_ops = {
> + .init_state = os02g10_init_state,
> +};
> +
> +static int os02g10_power_on(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> + struct os02g10 *os02g10 = to_os02g10(sd);
> + int ret;
> +
> + ret = regulator_bulk_enable(ARRAY_SIZE(os02g10_supply_name),
> + os02g10->supplies);
> + if (ret) {
> + dev_err(os02g10->dev, "failed to enable regulators\n");
> + return ret;
> + }
> +
> + /* T4: delay from DOVDD stable to MCLK on */
> + fsleep(5 * USEC_PER_MSEC);
> +
> + ret = clk_prepare_enable(os02g10->xclk);
> + if (ret) {
> + dev_err(os02g10->dev, "failed to enable clock\n");
> + goto err_regulator_off;
> + }
> +
> + /* T3: delay from DVDD stable to sensor power up stable */
> + fsleep(5 * USEC_PER_MSEC);
> +
> + gpiod_set_value_cansleep(os02g10->reset_gpio, 0);
> +
> + /* T5: delay from sensor power up stable to SCCB initialization */
> + fsleep(5 * USEC_PER_MSEC);
> +
> + return 0;
> +
> +err_regulator_off:
> + regulator_bulk_disable(ARRAY_SIZE(os02g10_supply_name), os02g10->supplies);
> + return ret;
> +}
> +
> +static int os02g10_power_off(struct device *dev)
> +{
> + struct v4l2_subdev *sd = dev_get_drvdata(dev);
> + struct os02g10 *os02g10 = to_os02g10(sd);
> +
> + clk_disable_unprepare(os02g10->xclk);
> + gpiod_set_value_cansleep(os02g10->reset_gpio, 1);
> + regulator_bulk_disable(ARRAY_SIZE(os02g10_supply_name), os02g10->supplies);
> +
> + return 0;
> +}
> +
> +static int os02g10_identify_module(struct os02g10 *os02g10)
> +{
> + u64 chip_id;
> + int ret;
> +
> + ret = os02g10_read(os02g10, OS02G10_REG_CHIPID, &chip_id, NULL);
> + if (ret)
> + return dev_err_probe(os02g10->dev, ret,
> + "failed to read chip id %x\n",
> + OS02G10_CHIPID);
> +
> + if (chip_id != OS02G10_CHIPID)
> + return dev_err_probe(os02g10->dev, -EIO,
> + "chip id mismatch: %x!=%llx\n",
> + OS02G10_CHIPID, chip_id);
> +
> + return 0;
> +}
> +
> +static int os02g10_parse_endpoint(struct os02g10 *os02g10)
> +{
> + struct v4l2_fwnode_endpoint bus_cfg = {
> + .bus_type = V4L2_MBUS_CSI2_DPHY,
> + };
> + unsigned long link_freq_bitmap;
> + struct fwnode_handle *ep;
> + int ret;
> +
> + ep = fwnode_graph_get_next_endpoint(dev_fwnode(os02g10->dev), NULL);
> + if (!ep)
You can omit this check.
> + return dev_err_probe(os02g10->dev, -ENXIO,
> + "Failed to get next endpoint\n");
> +
> + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
> + fwnode_handle_put(ep);
> + if (ret)
> + return ret;
> +
> + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
> + ret = dev_err_probe(os02g10->dev, -EINVAL,
> + "only 2 data lanes are supported\n");
> + goto error_out;
> + }
> +
> + ret = v4l2_link_freq_to_bitmap(os02g10->dev, bus_cfg.link_frequencies,
> + bus_cfg.nr_of_link_frequencies,
> + link_freq_menu_items,
> + ARRAY_SIZE(link_freq_menu_items),
> + &link_freq_bitmap);
> + if (ret) {
> + ret = dev_err_probe(os02g10->dev, -EINVAL,
> + "only 720MHz frequency is available\n");
> + goto error_out;
> + }
> +
> + os02g10->link_freq_index = __ffs(link_freq_bitmap);
Could you rely on the value of the control?
> +
> +error_out:
> + v4l2_fwnode_endpoint_free(&bus_cfg);
> +
> + return ret;
> +};
> +
> +static int os02g10_probe(struct i2c_client *client)
> +{
> + struct os02g10 *os02g10;
> + unsigned int xclk_freq;
> + int ret;
> +
> + os02g10 = devm_kzalloc(&client->dev, sizeof(*os02g10), GFP_KERNEL);
> + if (!os02g10)
> + return -ENOMEM;
> +
> + os02g10->dev = &client->dev;
> +
> + v4l2_i2c_subdev_init(&os02g10->sd, client, &os02g10_subdev_ops);
> + os02g10->sd.internal_ops = &os02g10_internal_ops;
> +
> + os02g10->cci = devm_cci_regmap_init_i2c(client, 8);
> + if (IS_ERR(os02g10->cci))
> + return dev_err_probe(os02g10->dev, PTR_ERR(os02g10->cci),
> + "failed to initialize CCI\n");
> +
> + /* Set Current page to 0 */
> + os02g10->current_page = 0;
> +
> + ret = devm_mutex_init(os02g10->dev, &os02g10->page_lock);
> + if (ret)
> + return dev_err_probe(os02g10->dev, ret,
> + "Failed to initialize lock\n");
> +
> + /* Get system clock (xvclk) */
> + os02g10->xclk = devm_v4l2_sensor_clk_get(os02g10->dev, NULL);
> + if (IS_ERR(os02g10->xclk))
> + return dev_err_probe(os02g10->dev, PTR_ERR(os02g10->xclk),
> + "failed to get xclk\n");
> +
> + xclk_freq = clk_get_rate(os02g10->xclk);
> + if (xclk_freq != OS02G10_XCLK_FREQ)
> + return dev_err_probe(os02g10->dev, -EINVAL,
> + "xclk frequency not supported: %u Hz\n",
> + xclk_freq);
> +
> + for (unsigned int i = 0; i < ARRAY_SIZE(os02g10_supply_name); i++)
> + os02g10->supplies[i].supply = os02g10_supply_name[i];
> +
> + ret = devm_regulator_bulk_get(os02g10->dev,
> + ARRAY_SIZE(os02g10_supply_name),
> + os02g10->supplies);
> + if (ret)
> + return dev_err_probe(os02g10->dev, ret,
> + "failed to get regulators\n");
> +
> + ret = os02g10_parse_endpoint(os02g10);
I'd do this first: in some cases driver probing ends up being done a few
times before it succeeds so getting regulators, GPIOs and clock is better
left after that.
> + if (ret)
> + return dev_err_probe(os02g10->dev, ret,
> + "failed to parse endpoint configuration\n");
> +
> + os02g10->reset_gpio = devm_gpiod_get_optional(os02g10->dev,
> + "reset", GPIOD_OUT_HIGH);
> + if (IS_ERR(os02g10->reset_gpio))
> + return dev_err_probe(os02g10->dev, PTR_ERR(os02g10->reset_gpio),
> + "failed to get reset GPIO\n");
> +
> + ret = os02g10_power_on(os02g10->dev);
> + if (ret)
> + return ret;
> +
> + ret = os02g10_identify_module(os02g10);
> + if (ret)
> + goto error_power_off;
> +
> + ret = os02g10_init_controls(os02g10);
> + if (ret)
> + goto error_power_off;
> +
> + /* Initialize subdev */
> + os02g10->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> + os02g10->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> + os02g10->pad.flags = MEDIA_PAD_FL_SOURCE;
> +
> + ret = media_entity_pads_init(&os02g10->sd.entity, 1, &os02g10->pad);
> + if (ret) {
> + dev_err_probe(os02g10->dev, ret, "failed to init entity pads\n");
> + goto error_handler_free;
> + }
> +
> + os02g10->sd.state_lock = os02g10->handler.lock;
> + ret = v4l2_subdev_init_finalize(&os02g10->sd);
> + if (ret) {
> + dev_err_probe(os02g10->dev, ret, "subdev init error\n");
> + goto error_media_entity;
> + }
> +
> + pm_runtime_set_active(os02g10->dev);
> + pm_runtime_enable(os02g10->dev);
> +
> + ret = v4l2_async_register_subdev_sensor(&os02g10->sd);
> + if (ret) {
> + dev_err_probe(os02g10->dev, ret,
> + "failed to register os02g10 sub-device\n");
> + goto error_subdev_cleanup;
> + }
> +
> + pm_runtime_idle(os02g10->dev);
A newline here?
> + return 0;
> +
> +error_subdev_cleanup:
> + v4l2_subdev_cleanup(&os02g10->sd);
> + pm_runtime_disable(os02g10->dev);
> + pm_runtime_set_suspended(os02g10->dev);
> +
> +error_media_entity:
> + media_entity_cleanup(&os02g10->sd.entity);
> +
> +error_handler_free:
> + v4l2_ctrl_handler_free(os02g10->sd.ctrl_handler);
> +
> +error_power_off:
> + os02g10_power_off(os02g10->dev);
> +
> + return ret;
> +}
> +
> +static void os02g10_remove(struct i2c_client *client)
> +{
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct os02g10 *os02g10 = to_os02g10(sd);
> +
> + v4l2_async_unregister_subdev(sd);
> + v4l2_subdev_cleanup(&os02g10->sd);
> + media_entity_cleanup(&sd->entity);
> + v4l2_ctrl_handler_free(os02g10->sd.ctrl_handler);
> +
> + pm_runtime_disable(&client->dev);
> + if (!pm_runtime_status_suspended(&client->dev)) {
> + os02g10_power_off(&client->dev);
> + pm_runtime_set_suspended(&client->dev);
> + }
> +}
> +
> +static DEFINE_RUNTIME_DEV_PM_OPS(os02g10_pm_ops,
> + os02g10_power_off, os02g10_power_on, NULL);
> +
> +static const struct of_device_id os02g10_id[] = {
> + { .compatible = "ovti,os02g10" },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, os02g10_id);
> +
> +static struct i2c_driver os02g10_driver = {
> + .driver = {
> + .name = "os02g10",
> + .pm = pm_ptr(&os02g10_pm_ops),
> + .of_match_table = os02g10_id,
> + },
> + .probe = os02g10_probe,
> + .remove = os02g10_remove,
> +};
> +module_i2c_driver(os02g10_driver);
> +
> +MODULE_DESCRIPTION("OS02G10 Camera Sensor Driver");
> +MODULE_AUTHOR("Tarang Raval <tarang.raval@siliconsignals.io>");
> +MODULE_AUTHOR("Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>");
> +MODULE_LICENSE("GPL");
--
Kind regards,
Sakari Ailus
^ permalink raw reply
* Re: [PATCH v1 3/4] ASoC: qcom: q6dsp: Update bit format support for secondary i2s
From: Konrad Dybcio @ 2026-04-14 9:54 UTC (permalink / raw)
To: Kumar Anurag, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Srinivas Kandagatla,
Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai
Cc: linux-arm-msm, devicetree, linux-kernel, linux-sound
In-Reply-To: <20260413091937.134469-4-kumar.singh@oss.qualcomm.com>
On 4/13/26 11:19 AM, Kumar Anurag wrote:
> Add 32bit for playback and capture over secondary mi2s.
>
> Signed-off-by: Kumar Anurag <kumar.singh@oss.qualcomm.com>
> ---
Would this apply to the other 5 I2S ports as well?
Konrad
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: reset: imx8mq: Add _N suffix to IMX8MQ_RESET_MIPI_CSI*_RESET
From: Robby Cai @ 2026-04-14 9:55 UTC (permalink / raw)
To: Philipp Zabel
Cc: robh, krzk+dt, conor+dt, Frank.Li, s.hauer, festevam, devicetree,
kernel, imx, linux-arm-kernel, linux-kernel, aisheng.dong
In-Reply-To: <d6cdea5f1a4f2eb3f7b73e6136c77020f444d8f0.camel@pengutronix.de>
On Tue, Mar 31, 2026 at 02:45:07PM +0200, Philipp Zabel wrote:
> On Di, 2026-03-31 at 18:13 +0800, Robby Cai wrote:
> > The assert logic of the MIPI CSI reset signals is active-low on i.MX8MQ,
> > but the existing names do not indicate this explicitly. To improve
> > consistency and clarity, append the _N suffix to all
> > IMX8MQ_RESET_MIPI_CSI*_RESET definitions. The deprecated
> > IMX8MQ_RESET_MIPI_CSI*_RESET versions remain temporarily for DT ABI
> > compatibility and will be removed at an appropriate time in the future.
>
> The register description in the latest reference manual I can download,
> IMX8MDQLQRM Rev. 3.1 (06/2021), still call these bits
> MIPI_CSI1_CORE_RESET and so on (without _N). There is no mention of
> polarity in the bitfield description. Is a documentation update
> planned?
Yes. A documentation update is already planned to clarify the reset polarity
(active-low) and naming. The current RM description is incomplete and will be
corrected in a future revision.
>
> Right now I'd say this improves clarity, but reduces consistency with
> existing documentation.
>
> Are these bits self-clearing, or can the reset be asserted by writing
> 0? As it stands, the CSI driver using these resets, imx8mq-mipi-csi2.c,
> only calls reset_control_assert() in imx8mq_mipi_csi_sw_reset():
>
> /*
> * these are most likely self-clearing reset bits. to make it
> * more clear, the reset-imx7 driver should implement the
> * .reset() operation.
> */
> ret = reset_control_assert(state->rst);
>
> This will probably have to be turned into a deassert together with the
> reset driver change.
No, these reset bits are not self-clearing.
According to the design team, the MIPI CSI reset logic on i.MX8MQ is identical
to MIPI DSI: the reset is active-low and must be explicitly deasserted.
Writing ��0�� asserts reset and it will remain asserted until cleared by software.
The current assumption in the CSI driver that these bits are self-clearing is
therefore incorrect. This was exposed by the landing patch [1].
To fix this properly, the reset-imx7 driver needs to reflect the correct polarity,
and the CSI driver should use deassert instead of only calling
reset_control_assert(). The RM will also be updated to clarify this behavior.
[1] https://git.linuxtv.org/media.git/commit/?id=6d79bb8fd2aa25afccbd6aeec2821722fa0b5db5
Regards,
Robby
^ permalink raw reply
* Re: [PATCH 09/11] media: iris: Add support to select core for dual core platforms
From: Konrad Dybcio @ 2026-04-14 9:51 UTC (permalink / raw)
To: Vishnu Reddy, Bryan O'Donoghue, Vikash Garodia,
Dikshita Agarwal, Abhinav Kumar, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joerg Roedel,
Will Deacon, Robin Murphy, Bjorn Andersson, Konrad Dybcio,
Stefan Schmidt, Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu
In-Reply-To: <20260414-glymur-v1-9-7d3d1cf57b16@oss.qualcomm.com>
On 4/14/26 7:00 AM, Vishnu Reddy wrote:
> Select the hardware core (vcodec) for a session, based on load when the
> platform supports dual vcodec cores. Assign the session to vcodec if its
> MBPF/MBPS capacity allows it, otherwise assign to vcodec1. Communicate
> the selected vcodec core to firmware using new HFI_PROP_CORE_ID property.
>
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
[...]
> + if (core_mbpf[0] + new_mbpf <= max_core_mbpf)
> + inst->core_id = BIT(0);
> + else if (dual_core && core_mbpf[1] + new_mbpf <= max_core_mbpf)
> + inst->core_id = BIT(1);
Let's store the core ID as an index and only wrap it in BIT() where
necessary to pass into the firmware
Konrad
^ permalink raw reply
* Re: [PATCH 08/11] media: iris: Add power sequence for Glymur
From: Konrad Dybcio @ 2026-04-14 9:49 UTC (permalink / raw)
To: Vishnu Reddy, Bryan O'Donoghue, Vikash Garodia,
Dikshita Agarwal, Abhinav Kumar, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joerg Roedel,
Will Deacon, Robin Murphy, Bjorn Andersson, Konrad Dybcio,
Stefan Schmidt, Hans Verkuil
Cc: linux-media, linux-arm-msm, devicetree, linux-kernel, iommu
In-Reply-To: <20260414-glymur-v1-8-7d3d1cf57b16@oss.qualcomm.com>
On 4/14/26 7:00 AM, Vishnu Reddy wrote:
> Add power sequence hooks for controller, vcodec and vcodec1. reuse the
> existing code where ever is possible. add vcodec1 power on and off code
> separately which has different power domains and clocks.
>
> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
> ---
> .../platform/qcom/iris/iris_platform_common.h | 9 ++
> drivers/media/platform/qcom/iris/iris_vpu3x.c | 123 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
> .../platform/qcom/iris/iris_vpu_register_defines.h | 7 ++
> 4 files changed, 140 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index 30e9d4d288c6..e3c1aff770dd 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -61,6 +61,9 @@ enum platform_clk_type {
> IRIS_VPP0_HW_CLK,
> IRIS_VPP1_HW_CLK,
> IRIS_APV_HW_CLK,
> + IRIS_AXI_VCODEC1_CLK,
> + IRIS_VCODEC1_CLK,
> + IRIS_VCODEC1_FREERUN_CLK,
> };
>
> struct platform_clk_data {
> @@ -208,6 +211,12 @@ enum platform_pm_domain_type {
> IRIS_CTRL_POWER_DOMAIN,
> IRIS_VCODEC_POWER_DOMAIN,
> IRIS_VPP0_HW_POWER_DOMAIN,
> + /*
> + * On Glymur, vcodec1 power domain is at the same index in pd_devs[]
> + * as IRIS_VPP0_HW_POWER_DOMAIN. Alias it so that the Glymur power
> + * domain table is indexed correctly.
> + */
> + IRIS_VCODEC1_POWER_DOMAIN = IRIS_VPP0_HW_POWER_DOMAIN,
This feels really fragile..
[...]
> +static bool iris_vpu36_hw1_power_collapsed(struct iris_core *core)
> +{
> + u32 value, pwr_status;
> +
> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
> + pwr_status = value & BIT(4);
> +
> + return pwr_status ? false : true;
return !pwr_status
Konrad
^ permalink raw reply
* Re: [PATCH 01/11] dt-bindings: media: qcom,glymur-iris: Add glymur video codec
From: Vishnu Reddy @ 2026-04-14 9:46 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil, linux-media, linux-arm-msm, devicetree,
linux-kernel, iommu
In-Reply-To: <20260414-lush-reindeer-of-storm-bbe918@quoll>
On 4/14/2026 12:55 PM, Krzysztof Kozlowski wrote:
> On Tue, Apr 14, 2026 at 10:29:57AM +0530, Vishnu Reddy wrote:
>> Add device tree binding for the Qualcomm Glymur Iris video codec. Glymur
>> is a new generation of video IP that introduces a dual-core architecture.
>> The second core brings its own power domain, clocks, and reset lines,
>> requiring additional power domains and clocks in the power sequence.
>>
>> Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
>> ---
>> .../bindings/media/qcom,glymur-iris.yaml | 220 +++++++++++++++++++++
>> include/dt-bindings/media/qcom,glymur-iris.h | 11 ++
>> 2 files changed, 231 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/media/qcom,glymur-iris.yaml b/Documentation/devicetree/bindings/media/qcom,glymur-iris.yaml
>> new file mode 100644
>> index 000000000000..10ee02cd1a7d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/qcom,glymur-iris.yaml
>> @@ -0,0 +1,220 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/media/qcom,glymur-iris.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm Glymur SoC Iris video encoder and decoder
>> +
>> +maintainers:
>> + - Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
>> +
>> +description:
>> + The Iris video processing unit on Qualcomm Glymur SoC is a video encode and
>> + decode accelerator.
>> +
>> +properties:
>> + compatible:
>> + const: qcom,glymur-iris
>> +
>> + reg:
>> + maxItems: 1
>> +
>> + clocks:
>> + maxItems: 9
>> +
>> + clock-names:
>> + items:
>> + - const: iface
>> + - const: core
>> + - const: vcodec0_core
> iface1 goes here
> core_freerun
> vcodec0_core_freerun
> and the rest, based on sm8750. Or which previous variant did you use as
> the base?
Ack, will use sm8750 as base and I'll update.
Thanks for the suggestion.
>
>> + - const: iface_ctrl
>> + - const: core_freerun
>> + - const: vcodec0_core_freerun
>> + - const: iface1
>> + - const: vcodec1_core
>> + - const: vcodec1_core_freerun
>> +
>> + dma-coherent: true
>> +
>> + firmware-name:
>> + maxItems: 1
>> +
>> + interconnects:
>> + maxItems: 2
>> +
>> + interconnect-names:
>> + items:
>> + - const: cpu-cfg
>> + - const: video-mem
>> +
>> + interrupts:
>> + maxItems: 1
>> +
>> + iommus:
>> + maxItems: 4
>> +
>> + iommu-map:
>> + maxItems: 1
>> +
>> + memory-region:
>> + maxItems: 1
>> +
>> + operating-points-v2: true
>> + opp-table:
>> + type: object
>> +
>> + power-domains:
>> + maxItems: 5
>> +
>> + power-domain-names:
>> + items:
>> + - const: venus
>> + - const: vcodec0
>> + - const: mxc
>> + - const: mmcx
>> + - const: vcodec1
>> +
>> + resets:
>> + maxItems: 6
>> +
>> + reset-names:
>> + items:
>> + - const: bus0
> bus1
> core
> vcodec0_core
Ack
>
>> + - const: bus_ctrl
>
>> + - const: core
>> + - const: vcodec0_core
>> + - const: bus1
>> + - const: vcodec1_core
>> +
>> +required:
>> + - compatible
>> + - reg
>> + - clocks
>> + - clock-names
>> + - dma-coherent
>> + - interconnects
>> + - interconnect-names
>> + - interrupts
>> + - iommus
>> + - memory-region
>> + - power-domains
>> + - power-domain-names
>> + - resets
>> + - reset-names
>> +
>> +unevaluatedProperties: false
> Use existing, most recent code as starting point.
Ack, will use sm8750.
>
>> +
>> +examples:
>> + - |
>> + #include <dt-bindings/interrupt-controller/arm-gic.h>
>> + #include <dt-bindings/media/qcom,glymur-iris.h>
>> + #include <dt-bindings/power/qcom,rpmhpd.h>
>> +
>> + video-codec@aa00000 {
>> + compatible = "qcom,glymur-iris";
>> + reg = <0x0aa00000 0xf0000>;
>> +
>> + clocks = <&gcc_video_axi0_clk>,
>> + <&videocc_mvs0c_clk>,
>> + <&videocc_mvs0_clk>,
>> + <&gcc_video_axi0c_clk>,
>> + <&videocc_mvs0c_freerun_clk>,
>> + <&videocc_mvs0_freerun_clk>,
>> + <&gcc_video_axi1_clk>,
>> + <&videocc_mvs1_clk>,
>> + <&videocc_mvs1_freerun_clk>;
>> + clock-names = "iface",
>> + "core",
>> + "vcodec0_core",
>> + "iface_ctrl",
>> + "core_freerun",
>> + "vcodec0_core_freerun",
>> + "iface1",
>> + "vcodec1_core",
>> + "vcodec1_core_freerun";
>> +
>> + dma-coherent;
>> +
>> + interconnects = <&hsc_noc_master_appss_proc &config_noc_slave_venus_cfg>,
>> + <&mmss_noc_master_video &mc_virt_slave_ebi1>;
>> + interconnect-names = "cpu-cfg",
>> + "video-mem";
>> +
>> + interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
>> +
>> + iommus = <&apps_smmu 0x1940 0x0>,
>> + <&apps_smmu 0x1943 0x0>,
>> + <&apps_smmu 0x1944 0x0>,
>> + <&apps_smmu 0x19e0 0x0>;
>> +
>> + iommu-map = <IRIS_FIRMWARE &apps_smmu 0x19e2 0x1>;
>> +
>> + memory-region = <&video_mem>;
>> +
>> + operating-points-v2 = <&iris_opp_table>;
>> +
>> + power-domains = <&videocc_mvs0c_gdsc>,
>> + <&videocc_mvs0_gdsc>,
>> + <&rpmhpd RPMHPD_MXC>,
>> + <&rpmhpd RPMHPD_MMCX>,
>> + <&videocc_mvs1_gdsc>;
>> + power-domain-names = "venus",
>> + "vcodec0",
>> + "mxc",
>> + "mmcx",
>> + "vcodec1";
>> +
>> + resets = <&gcc_video_axi0_clk_ares>,
>> + <&gcc_video_axi0c_clk_ares>,
>> + <&videocc_mvs0c_freerun_clk_ares>,
>> + <&videocc_mvs0_freerun_clk_ares>,
>> + <&gcc_video_axi1_clk_ares>,
>> + <&videocc_mvs1_freerun_clk_ares>;
>> + reset-names = "bus0",
>> + "bus_ctrl",
>> + "core",
>> + "vcodec0_core",
>> + "bus1",
>> + "vcodec1_core";
>> +
>> + iris_opp_table: opp-table {
>> + compatible = "operating-points-v2";
>> +
>> + opp-240000000 {
>> + opp-hz = /bits/ 64 <240000000 240000000 360000000>;
>> + required-opps = <&rpmhpd_opp_svs>,
>> + <&rpmhpd_opp_low_svs>;
>> + };
>> +
>> + opp-338000000 {
>> + opp-hz = /bits/ 64 <338000000 338000000 507000000>;
>> + required-opps = <&rpmhpd_opp_svs>,
>> + <&rpmhpd_opp_svs>;
>> + };
>> +
>> + opp-366000000 {
>> + opp-hz = /bits/ 64 <366000000 366000000 549000000>;
>> + required-opps = <&rpmhpd_opp_svs_l1>,
>> + <&rpmhpd_opp_svs_l1>;
>> + };
>> +
>> + opp-444000000 {
>> + opp-hz = /bits/ 64 <444000000 444000000 666000000>;
>> + required-opps = <&rpmhpd_opp_svs_l1>,
>> + <&rpmhpd_opp_nom>;
>> + };
>> +
>> + opp-533333334 {
>> + opp-hz = /bits/ 64 <533333334 533333334 800000000>;
>> + required-opps = <&rpmhpd_opp_svs_l1>,
>> + <&rpmhpd_opp_turbo>;
>> + };
>> +
>> + opp-655000000 {
>> + opp-hz = /bits/ 64 <655000000 655000000 982000000>;
>> + required-opps = <&rpmhpd_opp_nom>,
>> + <&rpmhpd_opp_turbo_l1>;
>> + };
>> + };
>> + };
>> diff --git a/include/dt-bindings/media/qcom,glymur-iris.h b/include/dt-bindings/media/qcom,glymur-iris.h
>> new file mode 100644
>> index 000000000000..5766db0b9247
>> --- /dev/null
>> +++ b/include/dt-bindings/media/qcom,glymur-iris.h
>> @@ -0,0 +1,11 @@
>> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
>> +/*
>> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
>> + */
>> +
>> +#ifndef _DT_BINDINGS_MEDIA_QCOM_GLYMUR_IRIS_H_
>> +#define _DT_BINDINGS_MEDIA_QCOM_GLYMUR_IRIS_H_
>> +
>> +#define IRIS_FIRMWARE 0
> For what is this define? IOMMU map? Binding is quiet about it, so
> probably this should have some prefix to make it obvious.
> IOMMU_? DEV_? What does this define express?
It's a function ID. I'll add prefix like this IOMMU_FID_IRIS_FIRMWARE.
Thanks,
Vishnu Reddy
>
> Best regards,
> Krzysztof
>
^ permalink raw reply
* Re: [PATCH 06/10] ARM: dts: qcom: msm8960: add SCM
From: Konrad Dybcio @ 2026-04-14 9:46 UTC (permalink / raw)
To: linux, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Konrad Dybcio
Cc: Krzysztof Kozlowski, linux-arm-msm, linux-clk, devicetree,
linux-kernel, phone-devel, Rudraksha Gupta
In-Reply-To: <20260414-msm8960-wifi-v1-6-007fda9d6134@smankusors.com>
On 4/13/26 8:55 PM, Antony Kurniawan Soemardi via B4 Relay wrote:
> From: Antony Kurniawan Soemardi <linux@smankusors.com>
>
> Add the Secure Channel Manager firmware device node to the MSM8960
> device tree. The SCM is required for secure communication between the
> application processor and other subsystems.
>
> Tested-by: Rudraksha Gupta <guptarud@gmail.com>
> Signed-off-by: Antony Kurniawan Soemardi <linux@smankusors.com>
> ---
> arch/arm/boot/dts/qcom/qcom-msm8960.dtsi | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
> index 1d5e97b6aa4b..bc3fd55e524a 100644
> --- a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
> +++ b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
> @@ -77,6 +77,15 @@ l2: l2-cache {
> };
> };
>
> + firmware {
> + scm {
> + compatible = "qcom,scm-msm8960", "qcom,scm";
> +
> + clocks = <&rpmcc RPM_DAYTONA_FABRIC_CLK>;
I'm wondering if this should be an interconnect resource, but from a
quick grepping, I think this is always supposed to be @ 64 MHz so
perhaps not really
(please tell me if you know more)
Konrad
^ permalink raw reply
* Re: [PATCH v2 2/2] media: i2c: add os02g10 image sensor driver
From: Elgin Perumbilly @ 2026-04-14 9:43 UTC (permalink / raw)
To: Laurent Pinchart
Cc: sakari.ailus@linux.intel.com, Tarang Raval, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Hans Verkuil,
Hans de Goede, Vladimir Zapolskiy, Mehdi Djait, Benjamin Mugnier,
Sylvain Petinot, Hardevsinh Palaniya, Jingjing Xiong,
linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <20260414092758.GE4061@killaraus.ideasonboard.com>
Hi Laurent,
> I sent a review comment on v1.
>
> On Tue, Apr 14, 2026 at 02:19:45PM +0530, Elgin Perumbilly wrote:
> > Add a v4l2 subdevice driver for the Omnivision os02g10 sensor.
> >
> > The Omnivision os02g10 is a CMOS image sensor with an active array size of
> > 1920 x 1080.
> >
> > The following features are supported:
> > - Manual exposure an gain control support
> > - vblank/hblank control support
> > - vflip/hflip control support
> > - Test pattern control support
> > - Supported resolution: 1920 x 1080 @ 30fps (SBGGR10)
> >
> > Signed-off-by: Elgin Perumbilly <elgin.perumbilly@siliconsignals.io>
> > Reviewed-by: Tarang Raval <tarang.raval@siliconsignals.io>
> > ---
> > MAINTAINERS | 1 +
> > drivers/media/i2c/Kconfig | 10 +
> > drivers/media/i2c/Makefile | 1 +
> > drivers/media/i2c/os02g10.c | 1039 +++++++++++++++++++++++++++++++++++
> > 4 files changed, 1051 insertions(+)
> > create mode 100644 drivers/media/i2c/os02g10.c
I have added a new function, os02g10_set_framefmt, which dynamically sets
the mode register.
Please let me know if I have missed anything or if further changes are
needed.
Best regards,
Elgin
^ permalink raw reply
* Re: [PATCH 10/10] ARM: dts: qcom: msm8960: huashan: enable Wi-Fi and Bluetooth
From: Konrad Dybcio @ 2026-04-14 9:41 UTC (permalink / raw)
To: linux, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Konrad Dybcio
Cc: Krzysztof Kozlowski, linux-arm-msm, linux-clk, devicetree,
linux-kernel, phone-devel, Rudraksha Gupta
In-Reply-To: <20260414-msm8960-wifi-v1-10-007fda9d6134@smankusors.com>
On 4/13/26 8:55 PM, Antony Kurniawan Soemardi via B4 Relay wrote:
> From: Antony Kurniawan Soemardi <linux@smankusors.com>
>
> Add Wi-Fi and Bluetooth support for Sony Xperia SP.
>
> Signed-off-by: Antony Kurniawan Soemardi <linux@smankusors.com>
> ---
> arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts | 19 +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts b/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts
> index 591dc837e600..79fa9bd038f2 100644
> --- a/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts
> +++ b/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts
> @@ -95,6 +95,25 @@ MATRIX_KEY(1, 1, KEY_CAMERA)
> status = "okay";
> };
>
> +&riva {
> + pinctrl-0 = <&riva_wlan_default_state>, <&riva_bt_default_state>;
> + pinctrl-1 = <&riva_wlan_sleep_state>, <&riva_bt_sleep_state>;
> + pinctrl-names = "default", "sleep";
You can probably move these pinctrl assignments to the SoC DTSI
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* [PATCH v6 3/3] pinctrl: aspeed: Add AST2700 SoC0 support
From: Billy Tsai @ 2026-04-14 9:39 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
In-Reply-To: <20260414-upstream_pinctrl-v6-0-709f2127da33@aspeedtech.com>
Add pinctrl support for the SoC0 instance of the ASPEED AST2700.
AST2700 consists of two interconnected SoC instances, each with its own
pinctrl register block.
The SoC0 pinctrl hardware closely follows the design found in previous
ASPEED BMC generations, allowing the driver to build upon the common
ASPEED pinctrl infrastructure.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
drivers/pinctrl/aspeed/Kconfig | 9 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c | 749 ++++++++++++++++++++++++
3 files changed, 759 insertions(+)
diff --git a/drivers/pinctrl/aspeed/Kconfig b/drivers/pinctrl/aspeed/Kconfig
index 1a4e5b9ed471..f9672cca891e 100644
--- a/drivers/pinctrl/aspeed/Kconfig
+++ b/drivers/pinctrl/aspeed/Kconfig
@@ -31,3 +31,12 @@ config PINCTRL_ASPEED_G6
help
Say Y here to enable pin controller support for Aspeed's 6th
generation SoCs. GPIO is provided by a separate GPIO driver.
+
+config PINCTRL_ASPEED_G7_SOC0
+ bool "Aspeed G7 SoC pin control"
+ depends on (ARCH_ASPEED || COMPILE_TEST) && OF
+ select PINCTRL_ASPEED
+ help
+ Say Y here to enable pin controller support for the SoC0 instance
+ of Aspeed's 7th generation SoCs. GPIO is provided by a separate
+ GPIO driver.
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
index db2a7600ae2b..0de524ca2c72 100644
--- a/drivers/pinctrl/aspeed/Makefile
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_ASPEED) += pinctrl-aspeed.o pinmux-aspeed.o
obj-$(CONFIG_PINCTRL_ASPEED_G4) += pinctrl-aspeed-g4.o
obj-$(CONFIG_PINCTRL_ASPEED_G5) += pinctrl-aspeed-g5.o
obj-$(CONFIG_PINCTRL_ASPEED_G6) += pinctrl-aspeed-g6.o
+obj-$(CONFIG_PINCTRL_ASPEED_G7_SOC0) += pinctrl-aspeed-g7-soc0.o
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c
new file mode 100644
index 000000000000..35a28b677318
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c
@@ -0,0 +1,749 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bitops.h>
+#include <linux/bits.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include "pinctrl-aspeed.h"
+#include "pinmux-aspeed.h"
+#include "../pinctrl-utils.h"
+
+#define SCU200 0x200 /* System Reset Control #1 */
+
+#define SCU010 0x010 /* Hardware Strap Register */
+#define SCU400 0x400 /* Multi-function Pin Control #1 */
+#define SCU404 0x404 /* Multi-function Pin Control #2 */
+#define SCU408 0x408 /* Multi-function Pin Control #3 */
+#define SCU40C 0x40C /* Multi-function Pin Control #3 */
+#define SCU410 0x410 /* USB Multi-function Control Register */
+#define SCU414 0x414 /* VGA Function Control Register */
+
+#define SCU480 0x480 /* GPIO18A0 IO Control Register */
+#define SCU484 0x484 /* GPIO18A1 IO Control Register */
+#define SCU488 0x488 /* GPIO18A2 IO Control Register */
+#define SCU48C 0x48c /* GPIO18A3 IO Control Register */
+#define SCU490 0x490 /* GPIO18A4 IO Control Register */
+#define SCU494 0x494 /* GPIO18A5 IO Control Register */
+#define SCU498 0x498 /* GPIO18A6 IO Control Register */
+#define SCU49C 0x49c /* GPIO18A7 IO Control Register */
+#define SCU4A0 0x4A0 /* GPIO18B0 IO Control Register */
+#define SCU4A4 0x4A4 /* GPIO18B1 IO Control Register */
+#define SCU4A8 0x4A8 /* GPIO18B2 IO Control Register */
+#define SCU4AC 0x4AC /* GPIO18B3 IO Control Register */
+
+enum {
+ AC14,
+ AE15,
+ AD14,
+ AE14,
+ AF14,
+ AB13,
+ AB14,
+ AF15,
+ AF13,
+ AC13,
+ AD13,
+ AE13,
+ JTAG_PORT,
+ PCIERC0_PERST,
+ PCIERC1_PERST,
+ PORTA_MODE,
+ PORTA_U2,
+ PORTB_MODE,
+ PORTB_U2,
+ PORTA_U2_PHY,
+ PORTB_U2_PHY,
+ PORTA_U3,
+ PORTB_U3,
+ PORTA_U3_PHY,
+ PORTB_U3_PHY,
+};
+
+SIG_EXPR_LIST_DECL_SEMG(AC14, EMMCCLK, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 0));
+SIG_EXPR_LIST_DECL_SESG(AC14, VB1CS, VB1, SIG_DESC_SET(SCU404, 0));
+PIN_DECL_2(AC14, GPIO18A0, EMMCCLK, VB1CS);
+
+SIG_EXPR_LIST_DECL_SEMG(AE15, EMMCCMD, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 1));
+SIG_EXPR_LIST_DECL_SESG(AE15, VB1CK, VB1, SIG_DESC_SET(SCU404, 1));
+PIN_DECL_2(AE15, GPIO18A1, EMMCCMD, VB1CK);
+
+SIG_EXPR_LIST_DECL_SEMG(AD14, EMMCDAT0, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 2));
+SIG_EXPR_LIST_DECL_SESG(AD14, VB1MOSI, VB1, SIG_DESC_SET(SCU404, 2));
+PIN_DECL_2(AD14, GPIO18A2, EMMCDAT0, VB1MOSI);
+
+SIG_EXPR_LIST_DECL_SEMG(AE14, EMMCDAT1, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 3));
+SIG_EXPR_LIST_DECL_SESG(AE14, VB1MISO, VB1, SIG_DESC_SET(SCU404, 3));
+PIN_DECL_2(AE14, GPIO18A3, EMMCDAT1, VB1MISO);
+
+SIG_EXPR_LIST_DECL_SEMG(AF14, EMMCDAT2, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 4));
+PIN_DECL_1(AF14, GPIO18A4, EMMCDAT2);
+
+SIG_EXPR_LIST_DECL_SEMG(AB13, EMMCDAT3, EMMCG4, EMMC, SIG_DESC_SET(SCU400, 5));
+PIN_DECL_1(AB13, GPIO18A5, EMMCDAT3);
+
+SIG_EXPR_LIST_DECL_SEMG(AB14, EMMCCDN, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 6));
+SIG_EXPR_LIST_DECL_SESG(AB14, VB0CS, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_2(AB14, GPIO18A6, EMMCCDN, VB0CS);
+
+SIG_EXPR_LIST_DECL_SEMG(AF15, EMMCWPN, EMMCG1, EMMC, SIG_DESC_SET(SCU400, 7));
+SIG_EXPR_LIST_DECL_SESG(AF15, VB0CK, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_2(AF15, GPIO18A7, EMMCWPN, VB0CK);
+
+SIG_EXPR_LIST_DECL_SESG(AF13, TSPRSTN, TSPRSTN, SIG_DESC_SET(SCU010, 9));
+SIG_EXPR_LIST_DECL_SEMG(AF13, EMMCDAT4, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 8));
+SIG_EXPR_LIST_DECL_SESG(AF13, VB0MOSI, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_3(AF13, GPIO18B0, TSPRSTN, EMMCDAT4, VB0MOSI);
+
+SIG_EXPR_LIST_DECL_SESG(AC13, UFSCLKI, UFSCLKI, SIG_DESC_SET(SCU010, 19));
+SIG_EXPR_LIST_DECL_SEMG(AC13, EMMCDAT5, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 9));
+SIG_EXPR_LIST_DECL_SESG(AC13, VB0MISO, VB0, SIG_DESC_SET(SCU010, 17));
+PIN_DECL_3(AC13, GPIO18B1, UFSCLKI, EMMCDAT5, VB0MISO);
+
+SIG_EXPR_LIST_DECL_SEMG(AD13, EMMCDAT6, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 10));
+SIG_EXPR_LIST_DECL_SESG(AD13, DDCCLK, VGADDC, SIG_DESC_SET(SCU404, 10));
+PIN_DECL_2(AD13, GPIO18B2, EMMCDAT6, DDCCLK);
+
+SIG_EXPR_LIST_DECL_SEMG(AE13, EMMCDAT7, EMMCG8, EMMC, SIG_DESC_SET(SCU400, 11));
+SIG_EXPR_LIST_DECL_SESG(AE13, DDCDAT, VGADDC, SIG_DESC_SET(SCU404, 11));
+PIN_DECL_2(AE13, GPIO18B3, EMMCDAT7, DDCDAT);
+
+GROUP_DECL(EMMCG1, AC14, AE15, AD14);
+GROUP_DECL(EMMCG4, AC14, AE15, AD14, AE14, AF14, AB13);
+GROUP_DECL(EMMCG8, AC14, AE15, AD14, AE14, AF14, AB13, AF13, AC13, AD13, AE13);
+GROUP_DECL(EMMCWPN, AF15);
+GROUP_DECL(EMMCCDN, AB14);
+FUNC_DECL_(EMMC, "EMMCG1", "EMMCG4", "EMMCG8", "EMMCWPN", "EMMCCDN");
+
+GROUP_DECL(VB1, AC14, AE15, AD14, AE14);
+GROUP_DECL(VB0, AF15, AB14, AF13, AC13);
+FUNC_DECL_2(VB, VB1, VB0);
+
+FUNC_GROUP_DECL(TSPRSTN, AF13);
+
+FUNC_GROUP_DECL(UFSCLKI, AC13);
+
+FUNC_GROUP_DECL(VGADDC, AD13, AE13);
+
+/* JTAG Port Selection */
+#define JTAG_PORT_PSP_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x0, 0 }
+#define JTAG_PORT_SSP_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x41, 0 }
+#define JTAG_PORT_TSP_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x42, 0 }
+#define JTAG_PORT_DDR_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x43, 0 }
+#define JTAG_PORT_USB3A_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x44, 0 }
+#define JTAG_PORT_USB3B_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x45, 0 }
+#define JTAG_PORT_PCIEA_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x46, 0 }
+#define JTAG_PORT_PCIEB_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x47, 0 }
+#define JTAG_PORT_JTAGM0_DESC { ASPEED_IP_SCU, SCU408, GENMASK(12, 5), 0x8, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGPSP, JTAG0, JTAGPSP, JTAG_PORT_PSP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGSSP, JTAG0, JTAGSSP, JTAG_PORT_SSP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGTSP, JTAG0, JTAGTSP, JTAG_PORT_TSP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGDDR, JTAG0, JTAGDDR, JTAG_PORT_DDR_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGUSB3A, JTAG0, JTAGUSB3A, JTAG_PORT_USB3A_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGUSB3B, JTAG0, JTAGUSB3B, JTAG_PORT_USB3B_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGPCIEA, JTAG0, JTAGPCIEA, JTAG_PORT_PCIEA_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGPCIEB, JTAG0, JTAGPCIEB, JTAG_PORT_PCIEB_DESC);
+SIG_EXPR_LIST_DECL_SEMG(JTAG_PORT, JTAGM0, JTAG0, JTAGM0, JTAG_PORT_JTAGM0_DESC);
+PIN_DECL_(JTAG_PORT, SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGPSP), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGSSP),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGTSP), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGDDR),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGUSB3A), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGUSB3B),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGPCIEA), SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGPCIEB),
+ SIG_EXPR_LIST_PTR(JTAG_PORT, JTAGM0));
+
+GROUP_DECL(JTAG0, JTAG_PORT);
+
+FUNC_DECL_1(JTAGPSP, JTAG0);
+FUNC_DECL_1(JTAGSSP, JTAG0);
+FUNC_DECL_1(JTAGTSP, JTAG0);
+FUNC_DECL_1(JTAGDDR, JTAG0);
+FUNC_DECL_1(JTAGUSB3A, JTAG0);
+FUNC_DECL_1(JTAGUSB3B, JTAG0);
+FUNC_DECL_1(JTAGPCIEA, JTAG0);
+FUNC_DECL_1(JTAGPCIEB, JTAG0);
+FUNC_DECL_1(JTAGM0, JTAG0);
+
+/* PCIe Reset Control */
+SIG_EXPR_LIST_DECL_SESG(PCIERC0_PERST, PCIERC0PERST, PCIERC0PERST, SIG_DESC_SET(SCU200, 21));
+PIN_DECL_(PCIERC0_PERST, SIG_EXPR_LIST_PTR(PCIERC0_PERST, PCIERC0PERST));
+FUNC_GROUP_DECL(PCIERC0PERST, PCIERC0_PERST);
+
+SIG_EXPR_LIST_DECL_SESG(PCIERC1_PERST, PCIERC1PERST, PCIERC1PERST, SIG_DESC_SET(SCU200, 19));
+PIN_DECL_(PCIERC1_PERST, SIG_EXPR_LIST_PTR(PCIERC1_PERST, PCIERC1PERST));
+FUNC_GROUP_DECL(PCIERC1PERST, PCIERC1_PERST);
+
+#define PORTA_MODE_HPD0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 0, 0 }
+#define PORTA_MODE_D0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 1, 0 }
+#define PORTA_MODE_H_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 2, 0 }
+#define PORTA_MODE_HP_DESC { ASPEED_IP_SCU, SCU410, GENMASK(25, 24), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AHPD0, USB2AH, USB2AHPD0, PORTA_MODE_HPD0_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AH, USB2AHAP, USB2AH, PORTA_MODE_H_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AHP, USB2AHAP, USB2AHP, PORTA_MODE_HP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTA_MODE, USB2AD0, USB2AHAP, USB2AD0, PORTA_MODE_D0_DESC);
+PIN_DECL_(PORTA_MODE, SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AHPD0),
+ SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AH), SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AHP),
+ SIG_EXPR_LIST_PTR(PORTA_MODE, USB2AD0));
+
+#define PORTA_U2_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 0, 0 }
+#define PORTA_U2_D1_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 1, 0 }
+#define PORTA_U2_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 2, 0 }
+#define PORTA_U2_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(3, 2), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHD1, USB2A, USB2AXHD1, PORTA_U2_XHD_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHPD1, USB2A, USB2AXHPD1, PORTA_U2_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXH, USB2AAP, USB2AXH, PORTA_U2_XH_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHP, USB2AAP, USB2AXHP, PORTA_U2_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXH2B, USB2ABP, USB2AXH2B, PORTA_U2_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AXHP2B, USB2ABP, USB2AXHP2B, PORTA_U2_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U2, USB2AD1, USB2ADAP, USB2AD1, PORTA_U2_D1_DESC);
+PIN_DECL_(PORTA_U2, SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHD1), SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHPD1),
+ SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXH), SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHP),
+ SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXH2B), SIG_EXPR_LIST_PTR(PORTA_U2, USB2AXHP2B),
+ SIG_EXPR_LIST_PTR(PORTA_U2, USB2AD1));
+
+#define PORTB_MODE_HPD0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 0, 0 }
+#define PORTB_MODE_D0_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 1, 0 }
+#define PORTB_MODE_H_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 2, 0 }
+#define PORTB_MODE_HP_DESC { ASPEED_IP_SCU, SCU410, GENMASK(29, 28), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BHPD0, USB2BH, USB2BHPD0, PORTB_MODE_HPD0_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BH, USB2BHBP, USB2BH, PORTB_MODE_H_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BHP, USB2BHBP, USB2BHP, PORTB_MODE_HP_DESC);
+SIG_EXPR_LIST_DECL_SEMG(PORTB_MODE, USB2BD0, USB2BHBP, USB2BD0, PORTB_MODE_D0_DESC);
+PIN_DECL_(PORTB_MODE, SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BHPD0),
+ SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BH), SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BHP),
+ SIG_EXPR_LIST_PTR(PORTB_MODE, USB2BD0));
+
+#define PORTB_U2_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 0, 0 }
+#define PORTB_U2_D1_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 1, 0 }
+#define PORTB_U2_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 2, 0 }
+#define PORTB_U2_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(7, 6), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHD1, USB2B, USB2BXHD1, PORTB_U2_XHD_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHPD1, USB2B, USB2BXHPD1, PORTB_U2_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXH, USB2BBP, USB2BXH, PORTB_U2_XH_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHP, USB2BBP, USB2BXHP, PORTB_U2_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXH2A, USB2BAP, USB2BXH2A, PORTB_U2_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BXHP2A, USB2BAP, USB2BXHP2A, PORTB_U2_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U2, USB2BD1, USB2BDBP, USB2BD1, PORTB_U2_D1_DESC);
+PIN_DECL_(PORTB_U2, SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHD1), SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHPD1),
+ SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXH), SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHP),
+ SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXH2A), SIG_EXPR_LIST_PTR(PORTB_U2, USB2BXHP2A),
+ SIG_EXPR_LIST_PTR(PORTB_U2, USB2BD1));
+/*
+ * USB2 virtual PHY pins.
+ *
+ * PORTA_U2_PHY and PORTB_U2_PHY are logical endpoints, not package pins.
+ * They alias existing USB2 expressions so pin groups can model direct and
+ * cross-coupled routing for host and mode paths.
+ *
+ * - USB2AAP/USB2ADAP/USB2AHAP: use PORTA_U2_PHY
+ * - USB2ABP : use PORTB_U2_PHY
+ * - USB2BBP/USB2BDBP/USB2BHBP: use PORTB_U2_PHY
+ * - USB2BAP : use PORTA_U2_PHY
+ *
+ * They do not have any registers to configure this behaviour; the goal is
+ * simply for the driver to prevent conflicting selections. For example,
+ * selecting group USB2ABP and USB2BBP at the same time should not be
+ * allowed.
+ */
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AXH, USB2AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AXHP, USB2AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2BXH2A, USB2BAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2BXHP2A, USB2BAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AD1, USB2ADAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AH, USB2AHAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AHP, USB2AHAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U2_PHY, USB2AD0, USB2AHAP);
+PIN_DECL_(PORTA_U2_PHY, SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AXH),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AXHP), SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2BXH2A),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2BXHP2A), SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AD1),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AH), SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AHP),
+ SIG_EXPR_LIST_PTR(PORTA_U2_PHY, USB2AD0));
+
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2AXH2B, USB2ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2AXHP2B, USB2ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BXH, USB2BBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BXHP, USB2BBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BD1, USB2BDBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BH, USB2BHBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BHP, USB2BHBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U2_PHY, USB2BD0, USB2BHBP);
+PIN_DECL_(PORTB_U2_PHY, SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2AXH2B),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2AXHP2B), SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BXH),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BXHP), SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BD1),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BH), SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BHP),
+ SIG_EXPR_LIST_PTR(PORTB_U2_PHY, USB2BD0));
+
+GROUP_DECL(USB2A, PORTA_U2);
+GROUP_DECL(USB2AAP, PORTA_U2, PORTA_U2_PHY);
+GROUP_DECL(USB2ABP, PORTA_U2, PORTB_U2_PHY);
+GROUP_DECL(USB2ADAP, PORTA_U2, PORTA_U2_PHY);
+GROUP_DECL(USB2AH, PORTA_MODE);
+GROUP_DECL(USB2AHAP, PORTA_MODE, PORTA_U2_PHY);
+
+FUNC_DECL_1(USB2AXHD1, USB2A);
+FUNC_DECL_1(USB2AXHPD1, USB2A);
+FUNC_DECL_1(USB2AXH, USB2AAP);
+FUNC_DECL_1(USB2AXHP, USB2AAP);
+FUNC_DECL_1(USB2AXH2B, USB2ABP);
+FUNC_DECL_1(USB2AXHP2B, USB2ABP);
+FUNC_DECL_1(USB2AD1, USB2ADAP);
+FUNC_DECL_1(USB2AHPD0, USB2AH);
+FUNC_DECL_1(USB2AH, USB2AHAP);
+FUNC_DECL_1(USB2AHP, USB2AHAP);
+FUNC_DECL_1(USB2AD0, USB2AHAP);
+
+GROUP_DECL(USB2B, PORTB_U2);
+GROUP_DECL(USB2BBP, PORTB_U2, PORTB_U2_PHY);
+GROUP_DECL(USB2BAP, PORTB_U2, PORTA_U2_PHY);
+GROUP_DECL(USB2BDBP, PORTB_U2, PORTB_U2_PHY);
+GROUP_DECL(USB2BH, PORTB_MODE);
+GROUP_DECL(USB2BHBP, PORTB_MODE, PORTB_U2_PHY);
+
+FUNC_DECL_1(USB2BXHD1, USB2B);
+FUNC_DECL_1(USB2BXHPD1, USB2B);
+FUNC_DECL_1(USB2BXH, USB2BBP);
+FUNC_DECL_1(USB2BXHP, USB2BBP);
+FUNC_DECL_1(USB2BXH2A, USB2BAP);
+FUNC_DECL_1(USB2BXHP2A, USB2BAP);
+FUNC_DECL_1(USB2BD1, USB2BDBP);
+FUNC_DECL_1(USB2BHPD0, USB2BH);
+FUNC_DECL_1(USB2BH, USB2BHBP);
+FUNC_DECL_1(USB2BHP, USB2BHBP);
+FUNC_DECL_1(USB2BD0, USB2BHBP);
+
+#define PORTA_U3_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(1, 0), 0, 0 }
+#define PORTA_U3_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(1, 0), 2, 0 }
+#define PORTA_U3_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(1, 0), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHD, USB3A, USB3AXHD, PORTA_U3_XHD_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHPD, USB3A, USB3AXHPD, PORTA_U3_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXH, USB3AAP, USB3AXH, PORTA_U3_XH_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHP, USB3AAP, USB3AXHP, PORTA_U3_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXH2B, USB3ABP, USB3AXH2B, PORTA_U3_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 9));
+SIG_EXPR_LIST_DECL_SEMG(PORTA_U3, USB3AXHP2B, USB3ABP, USB3AXHP2B, PORTA_U3_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 9));
+PIN_DECL_(PORTA_U3, SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHD), SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHPD),
+ SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXH), SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHP),
+ SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXH2B), SIG_EXPR_LIST_PTR(PORTA_U3, USB3AXHP2B));
+
+#define PORTB_U3_XHD_DESC { ASPEED_IP_SCU, SCU410, GENMASK(5, 4), 0, 0 }
+#define PORTB_U3_XH_DESC { ASPEED_IP_SCU, SCU410, GENMASK(5, 4), 2, 0 }
+#define PORTB_U3_XH2E_DESC { ASPEED_IP_SCU, SCU410, GENMASK(5, 4), 3, 0 }
+
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHD, USB3B, USB3BXHD, PORTB_U3_XHD_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHPD, USB3B, USB3BXHPD, PORTB_U3_XHD_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXH, USB3BBP, USB3BXH, PORTB_U3_XH_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHP, USB3BBP, USB3BXHP, PORTB_U3_XH_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXH2A, USB3BAP, USB3BXH2A, PORTB_U3_XH2E_DESC,
+ SIG_DESC_SET(SCU410, 10));
+SIG_EXPR_LIST_DECL_SEMG(PORTB_U3, USB3BXHP2A, USB3BAP, USB3BXHP2A, PORTB_U3_XH2E_DESC,
+ SIG_DESC_CLEAR(SCU410, 10));
+PIN_DECL_(PORTB_U3, SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHD), SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHPD),
+ SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXH), SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHP),
+ SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXH2A), SIG_EXPR_LIST_PTR(PORTB_U3, USB3BXHP2A));
+
+/*
+ * USB3 virtual PHY pins.
+ *
+ * PORTA_U3_PHY and PORTB_U3_PHY are logical endpoints, not package pins.
+ * They alias existing USB3 expressions so pin groups can model both direct and
+ * cross-coupled routing to PHY A/B.
+ *
+ * - USB3AAP: PORTA_U3 + PORTA_U3_PHY (A -> PHY A)
+ * - USB3ABP: PORTA_U3 + PORTB_U3_PHY (A -> PHY B)
+ * - USB3BBP: PORTB_U3 + PORTB_U3_PHY (B -> PHY B)
+ * - USB3BAP: PORTB_U3 + PORTA_U3_PHY (B -> PHY A)
+ *
+ * They do not have any registers to configure this behavior; the goal is
+ * simply for the driver to prevent conflicting selections. For example,
+ * selecting group USB3ABP and USB3BBP at the same time should not be
+ * allowed.
+ */
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3AXH, USB3AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3AXHP, USB3AAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3BXH2A, USB3BAP);
+SIG_EXPR_LIST_ALIAS(PORTA_U3_PHY, USB3BXHP2A, USB3BAP);
+PIN_DECL_(PORTA_U3_PHY, SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3AXH),
+ SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3AXHP), SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3BXH2A),
+ SIG_EXPR_LIST_PTR(PORTA_U3_PHY, USB3BXHP2A));
+
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3AXH2B, USB3ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3AXHP2B, USB3ABP);
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3BXH, USB3BBP);
+SIG_EXPR_LIST_ALIAS(PORTB_U3_PHY, USB3BXHP, USB3BBP);
+PIN_DECL_(PORTB_U3_PHY, SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3AXH2B),
+ SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3AXHP2B), SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3BXH),
+ SIG_EXPR_LIST_PTR(PORTB_U3_PHY, USB3BXHP));
+
+/* USB3A xHCI to vHUB */
+GROUP_DECL(USB3A, PORTA_U3);
+/* USB3A xHCI to USB3A PHY */
+GROUP_DECL(USB3AAP, PORTA_U3, PORTA_U3_PHY);
+/* USB3A xHCI to USB3B PHY */
+GROUP_DECL(USB3ABP, PORTA_U3, PORTB_U3_PHY);
+
+FUNC_DECL_1(USB3AXHD, USB3A);
+FUNC_DECL_1(USB3AXHPD, USB3A);
+FUNC_DECL_1(USB3AXH, USB3AAP);
+FUNC_DECL_1(USB3AXHP, USB3AAP);
+FUNC_DECL_1(USB3AXH2B, USB3ABP);
+FUNC_DECL_1(USB3AXHP2B, USB3ABP);
+
+/* USB3B xHCI to vHUB */
+GROUP_DECL(USB3B, PORTB_U3);
+/* USB3B xHCI to USB3A PHY */
+GROUP_DECL(USB3BAP, PORTB_U3, PORTA_U3_PHY);
+/* USB3B xHCI to USB3B PHY */
+GROUP_DECL(USB3BBP, PORTB_U3, PORTB_U3_PHY);
+
+FUNC_DECL_1(USB3BXHD, USB3B);
+FUNC_DECL_1(USB3BXHPD, USB3B);
+FUNC_DECL_1(USB3BXH, USB3BBP);
+FUNC_DECL_1(USB3BXHP, USB3BBP);
+FUNC_DECL_1(USB3BXH2A, USB3BAP);
+FUNC_DECL_1(USB3BXHP2A, USB3BAP);
+
+static const struct pinctrl_pin_desc aspeed_g7_soc0_pins[] = {
+ ASPEED_PINCTRL_PIN(AC14),
+ ASPEED_PINCTRL_PIN(AE15),
+ ASPEED_PINCTRL_PIN(AD14),
+ ASPEED_PINCTRL_PIN(AE14),
+ ASPEED_PINCTRL_PIN(AF14),
+ ASPEED_PINCTRL_PIN(AB13),
+ ASPEED_PINCTRL_PIN(AB14),
+ ASPEED_PINCTRL_PIN(AF15),
+ ASPEED_PINCTRL_PIN(AF13),
+ ASPEED_PINCTRL_PIN(AC13),
+ ASPEED_PINCTRL_PIN(AD13),
+ ASPEED_PINCTRL_PIN(AE13),
+ ASPEED_PINCTRL_PIN(JTAG_PORT),
+ ASPEED_PINCTRL_PIN(PCIERC0_PERST),
+ ASPEED_PINCTRL_PIN(PCIERC1_PERST),
+ ASPEED_PINCTRL_PIN(PORTA_MODE),
+ ASPEED_PINCTRL_PIN(PORTA_U2),
+ ASPEED_PINCTRL_PIN(PORTA_U3),
+ ASPEED_PINCTRL_PIN(PORTA_U2_PHY),
+ ASPEED_PINCTRL_PIN(PORTA_U3_PHY),
+ ASPEED_PINCTRL_PIN(PORTB_MODE),
+ ASPEED_PINCTRL_PIN(PORTB_U2),
+ ASPEED_PINCTRL_PIN(PORTB_U3),
+ ASPEED_PINCTRL_PIN(PORTB_U2_PHY),
+ ASPEED_PINCTRL_PIN(PORTB_U3_PHY),
+};
+
+static const struct aspeed_pin_group aspeed_g7_soc0_groups[] = {
+ ASPEED_PINCTRL_GROUP(EMMCCDN),
+ ASPEED_PINCTRL_GROUP(EMMCG1),
+ ASPEED_PINCTRL_GROUP(EMMCG4),
+ ASPEED_PINCTRL_GROUP(EMMCG8),
+ ASPEED_PINCTRL_GROUP(EMMCWPN),
+ ASPEED_PINCTRL_GROUP(TSPRSTN),
+ ASPEED_PINCTRL_GROUP(UFSCLKI),
+ ASPEED_PINCTRL_GROUP(VB0),
+ ASPEED_PINCTRL_GROUP(VB1),
+ ASPEED_PINCTRL_GROUP(VGADDC),
+ /* JTAG groups */
+ ASPEED_PINCTRL_GROUP(JTAG0),
+ /* PCIE RC groups */
+ ASPEED_PINCTRL_GROUP(PCIERC0PERST),
+ ASPEED_PINCTRL_GROUP(PCIERC1PERST),
+ /* USB3A groups */
+ ASPEED_PINCTRL_GROUP(USB3A),
+ ASPEED_PINCTRL_GROUP(USB3AAP),
+ ASPEED_PINCTRL_GROUP(USB3ABP),
+ /* USB3B groups */
+ ASPEED_PINCTRL_GROUP(USB3B),
+ ASPEED_PINCTRL_GROUP(USB3BAP),
+ ASPEED_PINCTRL_GROUP(USB3BBP),
+ /* USB2A groups */
+ ASPEED_PINCTRL_GROUP(USB2A),
+ ASPEED_PINCTRL_GROUP(USB2AAP),
+ ASPEED_PINCTRL_GROUP(USB2ABP),
+ ASPEED_PINCTRL_GROUP(USB2ADAP),
+ ASPEED_PINCTRL_GROUP(USB2AH),
+ ASPEED_PINCTRL_GROUP(USB2AHAP),
+ /* USB2B groups */
+ ASPEED_PINCTRL_GROUP(USB2B),
+ ASPEED_PINCTRL_GROUP(USB2BAP),
+ ASPEED_PINCTRL_GROUP(USB2BBP),
+ ASPEED_PINCTRL_GROUP(USB2BDBP),
+ ASPEED_PINCTRL_GROUP(USB2BH),
+ ASPEED_PINCTRL_GROUP(USB2BHBP),
+};
+
+static const struct aspeed_pin_function aspeed_g7_soc0_functions[] = {
+ ASPEED_PINCTRL_FUNC(EMMC),
+ ASPEED_PINCTRL_FUNC(TSPRSTN),
+ ASPEED_PINCTRL_FUNC(UFSCLKI),
+ ASPEED_PINCTRL_FUNC(VB),
+ ASPEED_PINCTRL_FUNC(VGADDC),
+ /* JTAG functions */
+ ASPEED_PINCTRL_FUNC(JTAGDDR),
+ ASPEED_PINCTRL_FUNC(JTAGM0),
+ ASPEED_PINCTRL_FUNC(JTAGPCIEA),
+ ASPEED_PINCTRL_FUNC(JTAGPCIEB),
+ ASPEED_PINCTRL_FUNC(JTAGPSP),
+ ASPEED_PINCTRL_FUNC(JTAGSSP),
+ ASPEED_PINCTRL_FUNC(JTAGTSP),
+ ASPEED_PINCTRL_FUNC(JTAGUSB3A),
+ ASPEED_PINCTRL_FUNC(JTAGUSB3B),
+ /* PCIE RC functions */
+ ASPEED_PINCTRL_FUNC(PCIERC0PERST),
+ ASPEED_PINCTRL_FUNC(PCIERC1PERST),
+ /* USB3A functions */
+ ASPEED_PINCTRL_FUNC(USB3AXH),
+ ASPEED_PINCTRL_FUNC(USB3AXH2B),
+ ASPEED_PINCTRL_FUNC(USB3AXHD),
+ ASPEED_PINCTRL_FUNC(USB3AXHP),
+ ASPEED_PINCTRL_FUNC(USB3AXHP2B),
+ ASPEED_PINCTRL_FUNC(USB3AXHPD),
+ /* USB3B functions */
+ ASPEED_PINCTRL_FUNC(USB3BXH),
+ ASPEED_PINCTRL_FUNC(USB3BXH2A),
+ ASPEED_PINCTRL_FUNC(USB3BXHD),
+ ASPEED_PINCTRL_FUNC(USB3BXHP),
+ ASPEED_PINCTRL_FUNC(USB3BXHP2A),
+ ASPEED_PINCTRL_FUNC(USB3BXHPD),
+ /* USB2A functions */
+ ASPEED_PINCTRL_FUNC(USB2AD0),
+ ASPEED_PINCTRL_FUNC(USB2AD1),
+ ASPEED_PINCTRL_FUNC(USB2AH),
+ ASPEED_PINCTRL_FUNC(USB2AHP),
+ ASPEED_PINCTRL_FUNC(USB2AHPD0),
+ ASPEED_PINCTRL_FUNC(USB2AXH),
+ ASPEED_PINCTRL_FUNC(USB2AXH2B),
+ ASPEED_PINCTRL_FUNC(USB2AXHD1),
+ ASPEED_PINCTRL_FUNC(USB2AXHP),
+ ASPEED_PINCTRL_FUNC(USB2AXHP2B),
+ ASPEED_PINCTRL_FUNC(USB2AXHPD1),
+ /* USB2B functions */
+ ASPEED_PINCTRL_FUNC(USB2BD0),
+ ASPEED_PINCTRL_FUNC(USB2BD1),
+ ASPEED_PINCTRL_FUNC(USB2BH),
+ ASPEED_PINCTRL_FUNC(USB2BHP),
+ ASPEED_PINCTRL_FUNC(USB2BHPD0),
+ ASPEED_PINCTRL_FUNC(USB2BXH),
+ ASPEED_PINCTRL_FUNC(USB2BXH2A),
+ ASPEED_PINCTRL_FUNC(USB2BXHD1),
+ ASPEED_PINCTRL_FUNC(USB2BXHP),
+ ASPEED_PINCTRL_FUNC(USB2BXHP2A),
+ ASPEED_PINCTRL_FUNC(USB2BXHPD1),
+};
+
+static const struct pinmux_ops aspeed_g7_soc0_pinmux_ops = {
+ .get_functions_count = aspeed_pinmux_get_fn_count,
+ .get_function_name = aspeed_pinmux_get_fn_name,
+ .get_function_groups = aspeed_pinmux_get_fn_groups,
+ .set_mux = aspeed_pinmux_set_mux,
+ .gpio_request_enable = aspeed_gpio_request_enable,
+ .strict = true,
+};
+
+static const struct pinctrl_ops aspeed_g7_soc0_pinctrl_ops = {
+ .get_groups_count = aspeed_pinctrl_get_groups_count,
+ .get_group_name = aspeed_pinctrl_get_group_name,
+ .get_group_pins = aspeed_pinctrl_get_group_pins,
+ .pin_dbg_show = aspeed_pinctrl_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_all,
+ .dt_free_map = pinctrl_utils_free_map,
+};
+
+static const struct pinconf_ops aspeed_g7_soc0_pinconf_ops = {
+ .is_generic = true,
+ .pin_config_get = aspeed_pin_config_get,
+ .pin_config_set = aspeed_pin_config_set,
+ .pin_config_group_get = aspeed_pin_config_group_get,
+ .pin_config_group_set = aspeed_pin_config_group_set,
+};
+
+/* pinctrl_desc */
+static const struct pinctrl_desc aspeed_g7_soc0_pinctrl_desc = {
+ .name = "aspeed-g7-soc0-pinctrl",
+ .pins = aspeed_g7_soc0_pins,
+ .npins = ARRAY_SIZE(aspeed_g7_soc0_pins),
+ .pctlops = &aspeed_g7_soc0_pinctrl_ops,
+ .pmxops = &aspeed_g7_soc0_pinmux_ops,
+ .confops = &aspeed_g7_soc0_pinconf_ops,
+};
+
+static const struct aspeed_pin_config aspeed_g7_soc0_configs[] = {
+ /* GPIO18A */
+ { PIN_CONFIG_DRIVE_STRENGTH, { AC14, AC14 }, SCU480, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AC14, AC14 }, SCU480, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AC14, AC14 }, SCU480, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AC14, AC14 }, SCU480, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AE15, AE15 }, SCU484, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AE15, AE15 }, SCU484, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AE15, AE15 }, SCU484, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AE15, AE15 }, SCU484, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AD14, AD14 }, SCU488, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AD14, AD14 }, SCU488, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AD14, AD14 }, SCU488, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AD14, AD14 }, SCU488, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AE14, AE14 }, SCU48C, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AE14, AE14 }, SCU48C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AE14, AE14 }, SCU48C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AE14, AE14 }, SCU48C, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AF14, AF14 }, SCU490, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AF14, AF14 }, SCU490, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AF14, AF14 }, SCU490, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AF14, AF14 }, SCU490, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AB13, AB13 }, SCU494, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AB13, AB13 }, SCU494, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AB13, AB13 }, SCU494, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AB13, AB13 }, SCU494, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AB14, AB14 }, SCU498, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AB14, AB14 }, SCU498, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AB14, AB14 }, SCU498, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AB14, AB14 }, SCU498, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AF15, AF15 }, SCU49C, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AF15, AF15 }, SCU49C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AF15, AF15 }, SCU49C, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AF15, AF15 }, SCU49C, BIT(5) },
+ /* GPIO18B */
+ { PIN_CONFIG_DRIVE_STRENGTH, { AF13, AF13 }, SCU4A0, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AF13, AF13 }, SCU4A0, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AF13, AF13 }, SCU4A0, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AF13, AF13 }, SCU4A0, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AC13, AC13 }, SCU4A4, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AC13, AC13 }, SCU4A4, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AC13, AC13 }, SCU4A4, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AC13, AC13 }, SCU4A4, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AD13, AD13 }, SCU4A8, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AD13, AD13 }, SCU4A8, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AD13, AD13 }, SCU4A8, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AD13, AD13 }, SCU4A8, BIT(5) },
+ { PIN_CONFIG_DRIVE_STRENGTH, { AE13, AE13 }, SCU4AC, GENMASK(3, 0) },
+ { PIN_CONFIG_BIAS_PULL_DOWN, { AE13, AE13 }, SCU4AC, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_PULL_UP, { AE13, AE13 }, SCU4AC, GENMASK(5, 4) },
+ { PIN_CONFIG_BIAS_DISABLE, { AE13, AE13 }, SCU4AC, BIT(5) },
+};
+
+static const struct aspeed_pin_config_map aspeed_g7_soc0_pin_config_map[] = {
+ { PIN_CONFIG_BIAS_PULL_DOWN, -1, 2, GENMASK(1, 0) },
+ { PIN_CONFIG_BIAS_PULL_UP, -1, 3, GENMASK(1, 0) },
+ { PIN_CONFIG_BIAS_DISABLE, -1, 0, BIT_MASK(0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 3, 0, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 6, 1, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 8, 2, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 11, 3, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 16, 4, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 18, 5, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 20, 6, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 23, 7, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 30, 8, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 32, 9, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 33, 10, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 35, 11, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 37, 12, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 38, 13, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 39, 14, GENMASK(3, 0) },
+ { PIN_CONFIG_DRIVE_STRENGTH, 41, 15, GENMASK(3, 0) },
+
+};
+
+static int aspeed_g7_soc0_sig_expr_set(struct aspeed_pinmux_data *ctx,
+ const struct aspeed_sig_expr *expr, bool enable)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < expr->ndescs; i++) {
+ const struct aspeed_sig_desc *desc = &expr->descs[i];
+ u32 pattern = enable ? desc->enable : desc->disable;
+ u32 val = (pattern << __ffs(desc->mask));
+
+ if (!ctx->maps[desc->ip])
+ return -ENODEV;
+
+ WARN_ON_ONCE(desc->ip != ASPEED_IP_SCU);
+
+ ret = regmap_update_bits(ctx->maps[desc->ip], desc->reg,
+ desc->mask, val);
+ if (ret)
+ return ret;
+ }
+
+ ret = aspeed_sig_expr_eval(ctx, expr, enable);
+ if (ret < 0)
+ return ret;
+
+ return ret ? 0 : -EPERM;
+}
+
+static const struct aspeed_pinmux_ops aspeed_g7_soc0_ops = {
+ .set = aspeed_g7_soc0_sig_expr_set,
+};
+
+static struct aspeed_pinctrl_data aspeed_g7_soc0_pinctrl_data = {
+ .pins = aspeed_g7_soc0_pins,
+ .npins = ARRAY_SIZE(aspeed_g7_soc0_pins),
+ .pinmux = {
+ .ops = &aspeed_g7_soc0_ops,
+ .groups = aspeed_g7_soc0_groups,
+ .ngroups = ARRAY_SIZE(aspeed_g7_soc0_groups),
+ .functions = aspeed_g7_soc0_functions,
+ .nfunctions = ARRAY_SIZE(aspeed_g7_soc0_functions),
+ },
+ .configs = aspeed_g7_soc0_configs,
+ .nconfigs = ARRAY_SIZE(aspeed_g7_soc0_configs),
+ .confmaps = aspeed_g7_soc0_pin_config_map,
+ .nconfmaps = ARRAY_SIZE(aspeed_g7_soc0_pin_config_map),
+};
+
+static int aspeed_g7_soc0_pinctrl_probe(struct platform_device *pdev)
+{
+ return aspeed_pinctrl_probe(pdev, &aspeed_g7_soc0_pinctrl_desc,
+ &aspeed_g7_soc0_pinctrl_data);
+}
+
+static const struct of_device_id aspeed_g7_soc0_pinctrl_match[] = {
+ { .compatible = "aspeed,ast2700-soc0-pinctrl" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, aspeed_g7_soc0_pinctrl_match);
+
+static struct platform_driver aspeed_g7_soc0_pinctrl_driver = {
+ .probe = aspeed_g7_soc0_pinctrl_probe,
+ .driver = {
+ .name = "aspeed-g7-soc0-pinctrl",
+ .of_match_table = aspeed_g7_soc0_pinctrl_match,
+ .suppress_bind_attrs = true,
+ },
+};
+
+static int __init aspeed_g7_soc0_pinctrl_init(void)
+{
+ return platform_driver_register(&aspeed_g7_soc0_pinctrl_driver);
+}
+arch_initcall(aspeed_g7_soc0_pinctrl_init);
--
2.34.1
^ permalink raw reply related
* [PATCH v6 2/3] dt-bindings: mfd: aspeed,ast2x00-scu: Describe AST2700 SCU0
From: Billy Tsai @ 2026-04-14 9:39 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
In-Reply-To: <20260414-upstream_pinctrl-v6-0-709f2127da33@aspeedtech.com>
AST2700 consists of two interconnected SoC instances, each with its own
System Control Unit (SCU). The SCU0 provides pin control, interrupt
controllers, clocks, resets, and address-space mappings for the
Secondary and Tertiary Service Processors (SSP and TSP).
Describe the SSP/TSP address mappings using the standard
memory-region and memory-region-names properties.
Disallow legacy child nodes that are not present on AST2700, including
p2a-control and smp-memram. The latter is unnecessary as software can
access the scratch registers via the SCU syscon.
Also allow the AST2700 SoC0 pin controller to be described as a child
node of the SCU0, and add an example illustrating the SCU0 layout,
including reserved-memory, interrupt controllers, and pinctrl.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../bindings/mfd/aspeed,ast2x00-scu.yaml | 112 +++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
index a87f31fce019..d65897576a40 100644
--- a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
+++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
@@ -46,6 +46,17 @@ properties:
'#reset-cells':
const: 1
+ memory-region:
+ items:
+ - description: Region mapped through the first SSP address window.
+ - description: Region mapped through the second SSP address window.
+ - description: Region mapped through the TSP address window.
+ memory-region-names:
+ items:
+ - const: ssp-0
+ - const: ssp-1
+ - const: tsp
+
patternProperties:
'^p2a-control@[0-9a-f]+$':
description: >
@@ -87,6 +98,7 @@ patternProperties:
- aspeed,ast2400-pinctrl
- aspeed,ast2500-pinctrl
- aspeed,ast2600-pinctrl
+ - aspeed,ast2700-soc0-pinctrl
required:
- compatible
@@ -156,6 +168,29 @@ required:
- '#clock-cells'
- '#reset-cells'
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ anyOf:
+ - const: aspeed,ast2700-scu0
+ - const: aspeed,ast2700-scu1
+ then:
+ patternProperties:
+ '^p2a-control@[0-9a-f]+$': false
+ '^smp-memram@[0-9a-f]+$': false
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: aspeed,ast2700-scu0
+ else:
+ properties:
+ memory-region: false
+ memory-region-names: false
+
additionalProperties: false
examples:
@@ -180,4 +215,81 @@ examples:
reg = <0x7c 0x4>, <0x150 0x8>;
};
};
+
+ - |
+ / {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ssp_region_0: memory@400000000 {
+ reg = <0x4 0x00000000 0x0 0x01000000>;
+ no-map;
+ };
+
+ ssp_region_1: memory@401000000 {
+ reg = <0x4 0x01000000 0x0 0x01000000>;
+ no-map;
+ };
+
+ tsp_region: memory@402000000 {
+ reg = <0x4 0x02000000 0x0 0x01000000>;
+ no-map;
+ };
+ };
+
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ syscon@12c02000 {
+ compatible = "aspeed,ast2700-scu0", "syscon", "simple-mfd";
+ reg = <0 0x12c02000 0 0x1000>;
+ ranges = <0x0 0x0 0x12c02000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ memory-region = <&ssp_region_0>, <&ssp_region_1>,
+ <&tsp_region>;
+ memory-region-names = "ssp-0", "ssp-1", "tsp";
+
+ silicon-id@0 {
+ compatible = "aspeed,ast2700-silicon-id", "aspeed,silicon-id";
+ reg = <0x0 0x4>;
+ };
+
+ interrupt-controller@1b0 {
+ compatible = "aspeed,ast2700-scu-ic0";
+ reg = <0x1b0 0x4>;
+ #interrupt-cells = <1>;
+ interrupts-extended = <&intc0 97>;
+ interrupt-controller;
+ };
+
+ interrupt-controller@1e0 {
+ compatible = "aspeed,ast2700-scu-ic1";
+ reg = <0x1e0 0x4>;
+ #interrupt-cells = <1>;
+ interrupts-extended = <&intc0 98>;
+ interrupt-controller;
+ };
+
+ pinctrl@400 {
+ compatible = "aspeed,ast2700-soc0-pinctrl";
+ reg = <0x400 0x318>;
+ emmc-state {
+ function = "EMMC";
+ groups = "EMMCG1";
+ };
+ };
+ };
+ };
+ };
+
...
--
2.34.1
^ permalink raw reply related
* [PATCH v6 1/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc0-pinctrl
From: Billy Tsai @ 2026-04-14 9:38 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
In-Reply-To: <20260414-upstream_pinctrl-v6-0-709f2127da33@aspeedtech.com>
Add a device tree binding for the pin controller found in the
ASPEED AST2700 SoC0.
The controller manages various peripheral functions such as eMMC, USB,
VGA DDC, JTAG, and PCIe root complex signals.
Describe the AST2700 SoC0 pin controller using standard pin multiplexing
and configuration properties.
Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
---
.../pinctrl/aspeed,ast2700-soc0-pinctrl.yaml | 170 +++++++++++++++++++++
1 file changed, 170 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml
new file mode 100644
index 000000000000..ca008cf9dc7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml
@@ -0,0 +1,170 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/aspeed,ast2700-soc0-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2700 SoC0 Pin Controller
+
+maintainers:
+ - Billy Tsai <billy_tsai@aspeedtech.com>
+
+description:
+ The AST2700 features a dual-SoC architecture with two interconnected SoCs,
+ each having its own System Control Unit (SCU) for independent pin control.
+ This pin controller manages the pin multiplexing for SoC0.
+
+ The SoC0 pin controller manages pin functions including eMMC, VGA DDC,
+ dual USB3/USB2 ports (A and B), JTAG, and PCIe root complex interfaces.
+
+properties:
+ compatible:
+ const: aspeed,ast2700-soc0-pinctrl
+ reg:
+ maxItems: 1
+
+patternProperties:
+ '-state$':
+ type: object
+ allOf:
+ - $ref: pinmux-node.yaml#
+ - $ref: pincfg-node.yaml#
+ - if:
+ required:
+ - pins
+ else:
+ properties:
+ drive-strength: false
+ bias-disable: false
+ bias-pull-up: false
+ bias-pull-down: false
+ additionalProperties: false
+
+ properties:
+ function:
+ enum:
+ - EMMC
+ - JTAGDDR
+ - JTAGM0
+ - JTAGPCIEA
+ - JTAGPCIEB
+ - JTAGPSP
+ - JTAGSSP
+ - JTAGTSP
+ - JTAGUSB3A
+ - JTAGUSB3B
+ - PCIERC0PERST
+ - PCIERC1PERST
+ - TSPRSTN
+ - UFSCLKI
+ - USB2AD0
+ - USB2AD1
+ - USB2AH
+ - USB2AHP
+ - USB2AHPD0
+ - USB2AXH
+ - USB2AXH2B
+ - USB2AXHD1
+ - USB2AXHP
+ - USB2AXHP2B
+ - USB2AXHPD1
+ - USB2BD0
+ - USB2BD1
+ - USB2BH
+ - USB2BHP
+ - USB2BHPD0
+ - USB2BXH
+ - USB2BXH2A
+ - USB2BXHD1
+ - USB2BXHP
+ - USB2BXHP2A
+ - USB2BXHPD1
+ - USB3AXH
+ - USB3AXH2B
+ - USB3AXHD
+ - USB3AXHP
+ - USB3AXHP2B
+ - USB3AXHPD
+ - USB3BXH
+ - USB3BXH2A
+ - USB3BXHD
+ - USB3BXHP
+ - USB3BXHP2A
+ - USB3BXHPD
+ - VB
+ - VGADDC
+
+ groups:
+ enum:
+ - EMMCCDN
+ - EMMCG1
+ - EMMCG4
+ - EMMCG8
+ - EMMCWPN
+ - JTAG0
+ - PCIERC0PERST
+ - PCIERC1PERST
+ - TSPRSTN
+ - UFSCLKI
+ - USB2A
+ - USB2AAP
+ - USB2ABP
+ - USB2ADAP
+ - USB2AH
+ - USB2AHAP
+ - USB2B
+ - USB2BAP
+ - USB2BBP
+ - USB2BDBP
+ - USB2BH
+ - USB2BHBP
+ - USB3A
+ - USB3AAP
+ - USB3ABP
+ - USB3B
+ - USB3BAP
+ - USB3BBP
+ - VB0
+ - VB1
+ - VGADDC
+ pins:
+ enum:
+ - AB13
+ - AB14
+ - AC13
+ - AC14
+ - AD13
+ - AD14
+ - AE13
+ - AE14
+ - AE15
+ - AF13
+ - AF14
+ - AF15
+
+ drive-strength:
+ enum: [3, 6, 8, 11, 16, 18, 20, 23, 30, 32, 33, 35, 37, 38, 39, 41]
+
+ bias-disable: true
+ bias-pull-up: true
+ bias-pull-down: true
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - $ref: pinctrl.yaml#
+
+additionalProperties: false
+
+examples:
+ - |
+ pinctrl@400 {
+ compatible = "aspeed,ast2700-soc0-pinctrl";
+ reg = <0x400 0x318>;
+ emmc-state {
+ function = "EMMC";
+ groups = "EMMCG1";
+ };
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v6 0/3] pinctrl: aspeed: Add AST2700 SoC0 support
From: Billy Tsai @ 2026-04-14 9:38 UTC (permalink / raw)
To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Billy Tsai,
Bartosz Golaszewski, Ryan Chen
Cc: Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, openbmc, linux-gpio, linux-clk
AST2700 is composed of two interconnected SoC instances, each providing
its own pin control hardware. This series introduces bindings describing
the AST2700 pinctrl architecture and adds pinctrl driver support for the
SoC0 instance.
The bindings document the AST2700 dual-SoC design and follow common
pinctrl conventions, while the SoC0 driver implementation builds upon
the existing ASPEED pinctrl infrastructure.
---
Changes in v6:
- Restrict AST2700 SoC0 pinctrl pin configuration properties
(`drive-strength` and `bias-*`) to `pins`-based state nodes in the
binding schema.
- Move `memory-region` and `memory-region-names` in the AST2x00 SCU
binding to top-level descriptions, and keep the conditional schema
only to disallow them for non-AST2700 SCU0 compatibles.
- Add bias pull-up, pull-down, and disable support for AST2700 SoC0
GPIO18A/GPIO18B pins in the pinctrl driver.
- Fix the USB2 Port B XH/XHP mux selector definitions to use the
correct `PORTB_U2_XH_DESC` setting.
- Link to v5: https://lore.kernel.org/r/20260331-upstream_pinctrl-v5-0-8994f59ff367@aspeedtech.com
Changes in v5:
- Complete the AST2700 SCU0 binding and disallow child nodes that are
not relevant for the hardware (p2a-control and smp-memram).
- Add examples for both the AST2700 SCU0 binding and the pinctrl binding,
ensuring they are valid against the schema.
- Rework the pinctrl binding example to be self-contained and independent
of the SCU binding.
- Reorder the binding patches so the pinctrl binding is introduced before
the SCU binding update, allowing the SCU example to be added cleanly.
- Adjust the binding accordingly to restrict drive-strength to the
supported values.
- Update the drive-strength table to match hardware-defined values.
- Link to v4: https://lore.kernel.org/r/20260306-upstream_pinctrl-v4-0-ad4e8ab8b489@aspeedtech.com
Changes in v4:
- Rename series title to "pinctrl: aspeed: Add AST2700 SoC0 support"
to make it specific to SoC0.
- Remove unnecessary SCU example from bindings.
- Fix Makefile newline to avoid patch warning.
- Make pinctrl data structures const and align with existing Aspeed drivers.
- Sort the arrays and enums alphabetically.
- Minor cleanups for consistency, no functional changes.
- Link to v3: https://lore.kernel.org/r/20260120-upstream_pinctrl-v3-0-868fbf8413b5@aspeedtech.com
Changes in v3:
dt-bindings: pinctrl: aspeed: AST2700 pinctrl improvements
- Improved binding descriptions for SoC0 and SoC1 to better explain the
AST2700 dual-SoC architecture with independent pin control blocks
- Switched from additionalProperties to patternProperties using the
'-state$' suffix to restrict child node naming
- Removed per-binding examples based on review feedback
- Added additionalProperties: false at the top level for stricter schema
validation
- Dropped the aspeed,ast2700-soc1-pinctrl binding, as the SoC1 pinctrl
registers follow a regular layout and can be described using an
existing generic pinctrl binding
- Updated the function and group enum lists to match the definitions
used by the AST2700 pinctrl driver
dt-bindings: mfd: aspeed: Add AST2700 SCU example with pinctrl
- Added a complete AST2700 SCU0 example demonstrating pinctrl integration
- Example covers both pin function/group configuration and pin
drive-strength settings
- Updated child node naming to use the '-state' suffix, following common
pinctrl conventions
pinctrl: aspeed: AST2700 SoC0 driver improvements
- Refactored pin and signal declarations to use common ASPEED pinmux
macros (SIG_EXPR_LIST_DECL_SEMG, SIG_EXPR_LIST_DECL_SESG, PIN_DECL_*)
- Added SCU010 register definition for hardware strap control
- Reworked code structure to better align with existing ASPEED pinctrl
drivers
- Link to v2: https://lore.kernel.org/r/20250904103401.88287-1-billy_tsai@aspeedtech.com
Changes in v2:
- Update pinctrl aspeed binding files.
- Update the commit message for pinctrl binding patch.
- Link to v1: https://lore.kernel.org/r/20250829073030.2749482-1-billy_tsai@aspeedtech.com
---
Billy Tsai (3):
dt-bindings: pinctrl: Add aspeed,ast2700-soc0-pinctrl
dt-bindings: mfd: aspeed,ast2x00-scu: Describe AST2700 SCU0
pinctrl: aspeed: Add AST2700 SoC0 support
.../bindings/mfd/aspeed,ast2x00-scu.yaml | 112 +++
.../pinctrl/aspeed,ast2700-soc0-pinctrl.yaml | 170 +++++
drivers/pinctrl/aspeed/Kconfig | 9 +
drivers/pinctrl/aspeed/Makefile | 1 +
drivers/pinctrl/aspeed/pinctrl-aspeed-g7-soc0.c | 749 +++++++++++++++++++++
5 files changed, 1041 insertions(+)
---
base-commit: af4e9ef3d78420feb8fe58cd9a1ab80c501b3c08
change-id: 20251215-upstream_pinctrl-8f195df0a975
Best regards,
--
Billy Tsai <billy_tsai@aspeedtech.com>
^ permalink raw reply
* Re: [PATCH 07/10] ARM: dts: qcom: msm8960: add SMEM & hwmutex
From: Konrad Dybcio @ 2026-04-14 9:38 UTC (permalink / raw)
To: linux, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Konrad Dybcio
Cc: Krzysztof Kozlowski, linux-arm-msm, linux-clk, devicetree,
linux-kernel, phone-devel, Rudraksha Gupta
In-Reply-To: <20260414-msm8960-wifi-v1-7-007fda9d6134@smankusors.com>
On 4/13/26 8:55 PM, Antony Kurniawan Soemardi via B4 Relay wrote:
> From: Antony Kurniawan Soemardi <linux@smankusors.com>
>
> Enable shared memory communication and add the SFPB mutex for MSM8960.
> These provide the foundation for inter-processor communication with the
> Riva (BT + Wi-Fi) subsystem.
>
> Tested-by: Rudraksha Gupta <guptarud@gmail.com>
> Signed-off-by: Antony Kurniawan Soemardi <linux@smankusors.com>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH 05/11] media: iris: Enable Secure PAS support with IOMMU managed by Linux
From: Mukesh Ojha @ 2026-04-14 9:33 UTC (permalink / raw)
To: Vishnu Reddy
Cc: Bryan O'Donoghue, Vikash Garodia, Dikshita Agarwal,
Abhinav Kumar, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Joerg Roedel, Will Deacon,
Robin Murphy, Bjorn Andersson, Konrad Dybcio, Stefan Schmidt,
Hans Verkuil, linux-media, linux-arm-msm, devicetree,
linux-kernel, iommu
In-Reply-To: <20260414063128.6ass64wfi7nmtzti@hu-mojha-hyd.qualcomm.com>
On Tue, Apr 14, 2026 at 12:01:28PM +0530, Mukesh Ojha wrote:
> On Tue, Apr 14, 2026 at 10:30:01AM +0530, Vishnu Reddy wrote:
> > From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> >
> > Most Qualcomm platforms feature a proprietary hypervisor (such as Gunyah
> > or QHEE), which typically handles IOMMU configuration. This includes
> > mapping memory regions and device memory resources for remote processors
> > by intercepting qcom_scm_pas_auth_and_reset() calls. These mappings are
> > later removed during teardown. Additionally, SHM bridge setup is required
> > to enable memory protection for both remoteproc metadata and its memory
> > regions.
> >
> > When the hypervisor is absent, the operating system must perform these
> > configurations instead.
> >
> > Support for handling IOMMU and SHM setup in the absence of a hypervisor
> > is now in place. Extend the Iris driver to enable this functionality on
> > platforms where IOMMU is managed by Linux (i.e., non-Gunyah, non-QHEE).
> >
> > Additionally, the Iris driver must map the firmware and its required
> > resources to the firmware SID, which is now specified via iommu-map in
> > the device tree.
> >
> > Co-developed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > Signed-off-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
> > Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
> > Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
This works as long as IRIS does not have optional resources. Once it
starts needing mandatory resources like some peripheral access mapped
before IRIS is brought out of reset, it will need a resource table SCM
call, which we currently added for remote processors like ADSP and CDSP.
Let me know if you have plans to add that. I have a few sets of changes
in the remoteproc resource table and an API which we added in the
initial series that I could bring in.
-Mukesh
^ permalink raw reply
* Re: [PATCH 0/3] arm-smmu-v3: Add PMCG child support and update PMU MMIO mapping
From: Robin Murphy @ 2026-04-14 9:32 UTC (permalink / raw)
To: Peng Fan
Cc: Will Deacon, Joerg Roedel, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Mark Rutland, linux-arm-kernel, iommu, devicetree,
linux-kernel, linux-perf-users, Peng Fan
In-Reply-To: <ad3w/P1vA2uKsV/o@shlinux89>
On 2026-04-14 8:47 am, Peng Fan wrote:
> Hi Robin,
>
> On Fri, Apr 10, 2026 at 01:07:29PM +0100, Robin Murphy wrote:
>> On 08/04/2026 2:47 pm, Peng Fan wrote:
>>> On Wed, Apr 08, 2026 at 12:15:31PM +0100, Robin Murphy wrote:
>>>> On 2026-04-08 8:51 am, Peng Fan (OSS) wrote:
>>>>> This patch series adds proper support for describing and probing the
>>>>> Arm SMMU v3 PMCG (Performance Monitor Control Group) as a child node of
>>>>> the SMMU in Devicetree, and updates the relevant drivers accordingly.
>>>>>
>>>>> The SMMU v3 architecture allows an optional PMCG block, typically
>>>>> associated with TCUs, to be implemented within the SMMU register
>>>>> address space. For example, mmu700 PMCG is at the offset 0x2000 of the
>>>>> TCU page 0.
>>>>
>>>> But what's wrong with the existing binding? Especially given that it even has
>>>> an upstream user already:
>>>>
>>>> https://git.kernel.org/torvalds/c/aef9703dcbf8
>>>>
>>>>> Patch 1 updates the SMMU v3 Devicetree binding to allow PMCG child nodes,
>>>>> referencing the existing arm,smmu-v3-pmcg binding.
>>>>>
>>>>> Patch 2 updates the arm-smmu-v3 driver to populate platform devices for
>>>>> child nodes described in DT once the SMMU probe succeeds.
>>>>>
>>>>> Patch 3 updates the SMMUv3 PMU driver to correctly handle MMIO mapping when
>>>>> PMCG is described as a child node. The PMCG registers occupy a sub-region
>>>>> of the parent SMMU MMIO window, which is already requested by the SMMU
>>>>
>>>> That has not been the case since 52f3fab0067d ("iommu/arm-smmu-v3: Don't
>>>> reserve implementation defined register space") nearly 6 years ago, where the
>>>> whole purpose was to support Arm's PMCG implementation properly. What kernel
>>>> is this based on?
>>>
>>> Seems I am wrong. I thought PMCG is in page 0, so there were resource
>>> conflicts. I just retest without this patchset, all goes well.
>>>
>>> But from dt perspective, should the TCU PMCG node be child node of
>>> SMMU node?
>>
>> No. PMCGs can be used entirely independently of the SMMU itself, and while
>> most of the events do relate to SMMU translation and thus aren't necessarily
>> meaningful if it's not in use, there are still some which can be useful for
>> basic traffic counting, monitoring GPT/translation activity from _other_
>> security states (if observation is delegated to Non-Secure) and possibly
>> other things, even if the "main" Non-Secure SMMU interface isn't advertised
>> at all. It would be unreasonable to require the SMMU node to be present and
>> enabled *and* have a driver to populate PMCGs, to monitor events which are
>> outside the scope of that driver.
>
> Thanks for explaining this in detail.
>
> Just have one more question, we are using mmu-700, but MMU-700 implementation
> defined TCU and TBU events are not supported.
>
> Should we introduce a compatible string saying "arm,mmu700-tcu-pmcg" or
> "arm,mmu700-tbu-pmcg"? TBH, I have not checked MMU600(AE) or else.
MMU-700 and all other Arm implementations are still fully compatible
with "arm,mmu-600-pmcg" in terms of what that means. That lets the
driver correctly construct the "identifier" attribute, which then allows
userspace to know what exact PMU implementation it is.
We don't maintain ever-growing lists of aliases for imp-def events in
the kernel driver, same as we don't for CPU PMUs either. Generally,
anyone who has reason to go near those is likely to already have the TRM
to hand and thus have the encodings anyway, but I suppose you could add
jevents with the proper meaningful descriptions if you really wanted to.
Thanks,
Robin.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox