Devicetree
 help / color / mirror / Atom feed
* RE: [PATCH v2 2/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY binding
From: Hongxing Zhu @ 2024-04-03  5:16 UTC (permalink / raw)
  To: Conor Dooley, Frank Li
  Cc: vkoul@kernel.org, kishon@kernel.org, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
	linux-phy@lists.infradead.org, devicetree@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, kernel@pengutronix.de,
	imx@lists.linux.dev
In-Reply-To: <20240402-anemic-aerospace-bc428fff280c@spud>


> -----Original Message-----
> From: Conor Dooley <conor@kernel.org>
> Sent: 2024年4月3日 2:17
> To: Frank Li <frank.li@nxp.com>
> Cc: Hongxing Zhu <hongxing.zhu@nxp.com>; vkoul@kernel.org;
> kishon@kernel.org; robh+dt@kernel.org; krzysztof.kozlowski+dt@linaro.org;
> conor+dt@kernel.org; linux-phy@lists.infradead.org; devicetree@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; linux-kernel@vger.kernel.org;
> kernel@pengutronix.de; imx@lists.linux.dev
> Subject: Re: [PATCH v2 2/3] dt-bindings: phy: Add i.MX8Q HSIO SerDes PHY
> binding
> 
> On Tue, Apr 02, 2024 at 10:23:45AM -0400, Frank Li wrote:
> > On Tue, Apr 02, 2024 at 01:45:03PM +0800, Richard Zhu wrote:
> > > Add i.MX8QM and i.MX8QXP HSIO SerDes PHY binding.
> > > - Use the controller ID to specify which controller is binded to the
> > > PHY.
> > > - Introduce one HSIO configuration, mandatory required to set
> > > "PCIE_AB_SELECT" and "PHY_X1_EPCS_SEL" during the initialization.
> > >
> > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> >
> > You missed all conor's comments.
> > Please double check v1's comments.
> 
Hi Frank:
Thanks a lot for your reminder.
It's my fault that I missed this email.

> > > +  fsl,refclk-pad-mode:
> > > +    description: |
> > > +      Specifies the mode of the refclk pad used. It can be UNUSED(PHY
> > > +      refclock is derived from SoC internal source), INPUT(PHY refclock
> > > +      is provided externally via the refclk pad) or OUTPUT(PHY refclock
> > > +      is derived from SoC internal source and provided on the refclk pad).
> > > +      Refer include/dt-bindings/phy/phy-imx8-pcie.h for the constants
> > > +      to be used.
> > > +    $ref: /schemas/types.yaml#/definitions/uint32
> > > +    enum: [ 0, 1, 2 ]
> >
> > I remember needn't enum because there are header file.
> 
> Yah, specifically my comments about this property were missed and were
> probably the most meaningful comments I left.
Hi Conor:
I'm so sorry about it.
I made the mistake missing your last review email.
Would follow your comments in next review cycle.

Best Regards
Richard Zhu
> 
> Thanks for the reminder Frank.

^ permalink raw reply

* Re: [PATCH 1/7] arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
From: Shawn Guo @ 2024-04-03  4:44 UTC (permalink / raw)
  To: Frank Li
  Cc: Fabio Estevam, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, NXP Linux Team,
	Marcel Ziswiler, Philippe Schenker, Max Krummenacher,
	Alexander Stein, Joakim Zhang, devicetree, linux-arm-kernel,
	linux-kernel, stable
In-Reply-To: <ZgzIjziArPh8wnHA@lizhi-Precision-Tower-5810>

On Tue, Apr 02, 2024 at 11:10:07PM -0400, Frank Li wrote:
> On Wed, Apr 03, 2024 at 09:41:26AM +0800, Shawn Guo wrote:
> > On Tue, Apr 02, 2024 at 11:09:17AM -0400, Frank Li wrote:
> > > On Mon, Apr 01, 2024 at 08:04:56PM -0300, Fabio Estevam wrote:
> > > > On Mon, Apr 1, 2024 at 7:25 PM Frank Li <Frank.Li@nxp.com> wrote:
> > > > >
> > > > > lpcg's arg0 should use clock indices instead of index.
> > > > >
> > > > > pwm0_lpcg: clock-controller@5d400000 {
> > > > >         ...                                                // Col1  Col2
> > > > >         clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 0     0
> > > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 1     1
> > > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 2     4
> > > > >                  <&lsio_bus_clk>,                          // 3     5
> > > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;  // 4     6
> > > > >         clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>,
> > > > >                         <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>,
> > > > >                         <IMX_LPCG_CLK_6>;
> > > > > };
> > > > >
> > > > > Col1: index, which exited dts try to get.
> > > > 
> > > > I cannot understand this sentence, sorry.
> > > 
> > > This base on downstream dts code.  Downstream code use index in 'Col1' to
> > > get clock.
> > 
> > So s/exited/existing you meant?
> 
> Yes, sorry for typo. 

I fixed the typo and applied the series, thanks!

Shawn


^ permalink raw reply

* [PATCH v5 3/3] arm64: dts: qcom: apq8016: Add Schneider HMIBSC board DTS
From: Sumit Garg @ 2024-04-03  4:34 UTC (permalink / raw)
  To: linux-arm-msm, devicetree
  Cc: andersson, konrad.dybcio, robh+dt, krzysztof.kozlowski+dt,
	conor+dt, stephan, caleb.connolly, neil.armstrong,
	dmitry.baryshkov, laetitia.mariottini, pascal.eberhard,
	abdou.saker, jimmy.lalande, benjamin.missey, daniel.thompson,
	linux-kernel, Sumit Garg, Jagdish Gediya
In-Reply-To: <20240403043416.3800259-1-sumit.garg@linaro.org>

Add Schneider Electric HMIBSC board DTS. The HMIBSC board is an IIoT Edge
Box Core board based on the Qualcomm APQ8016E SoC.

Support for Schneider Electric HMIBSC. Features:
- Qualcomm Snapdragon 410C SoC - APQ8016 (4xCortex A53, Adreno 306)
- 1GiB RAM
- 8GiB eMMC, SD slot
- WiFi and Bluetooth
- 2x Host, 1x Device USB port
- HDMI
- Discrete TPM2 chip over SPI
- USB ethernet adaptors (soldered)

Co-developed-by: Jagdish Gediya <jagdish.gediya@linaro.org>
Signed-off-by: Jagdish Gediya <jagdish.gediya@linaro.org>
Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org>
Reviewed-by: Stephan Gerhold <stephan@gerhold.net>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
---
 arch/arm64/boot/dts/qcom/Makefile             |   1 +
 .../dts/qcom/apq8016-schneider-hmibsc.dts     | 491 ++++++++++++++++++
 2 files changed, 492 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts

diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 39889d5f8e12..ad55e52e950b 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -5,6 +5,7 @@ apq8016-sbc-usb-host-dtbs	:= apq8016-sbc.dtb apq8016-sbc-usb-host.dtbo
 
 dtb-$(CONFIG_ARCH_QCOM)	+= apq8016-sbc-usb-host.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= apq8016-sbc-d3-camera-mezzanine.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= apq8016-schneider-hmibsc.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= apq8039-t2.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= apq8094-sony-xperia-kitakami-karin_windy.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= apq8096-db820c.dtb
diff --git a/arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts b/arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts
new file mode 100644
index 000000000000..75c6137e5a11
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Linaro Ltd.
+ */
+
+/dts-v1/;
+
+#include "msm8916-pm8916.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
+#include <dt-bindings/sound/apq8016-lpass.h>
+
+/ {
+	model = "Schneider Electric HMIBSC Board";
+	compatible = "schneider,apq8016-hmibsc", "qcom,apq8016";
+
+	aliases {
+		i2c1 = &blsp_i2c6;
+		i2c3 = &blsp_i2c4;
+		i2c4 = &blsp_i2c3;
+		mmc0 = &sdhc_1; /* eMMC */
+		mmc1 = &sdhc_2; /* SD card */
+		serial0 = &blsp_uart1;
+		serial1 = &blsp_uart2;
+		spi0 = &blsp_spi5;
+		usid0 = &pm8916_0;
+	};
+
+	chosen {
+		stdout-path = "serial0";
+	};
+
+	hdmi-out {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con: endpoint {
+				remote-endpoint = <&adv7533_out>;
+			};
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		autorepeat;
+		pinctrl-0 = <&msm_key_volp_n_default>;
+		pinctrl-names = "default";
+
+		button {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&tlmm 107 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&pm8916_mpps_leds>;
+		pinctrl-names = "default";
+
+		led-1 {
+			function = LED_FUNCTION_WLAN;
+			color = <LED_COLOR_ID_YELLOW>;
+			gpios = <&pm8916_mpps 2 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "phy0tx";
+			default-state = "off";
+		};
+
+		led-2 {
+			function = LED_FUNCTION_BLUETOOTH;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pm8916_mpps 3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "bluetooth-power";
+			default-state = "off";
+		};
+	};
+
+	memory@80000000 {
+		reg = <0 0x80000000 0 0x40000000>;
+	};
+
+	reserved-memory {
+		ramoops@bff00000 {
+			compatible = "ramoops";
+			reg = <0x0 0xbff00000 0x0 0x100000>;
+			record-size = <0x20000>;
+			console-size = <0x20000>;
+			ftrace-size = <0x20000>;
+			ecc-size = <16>;
+		};
+	};
+
+	usb-hub {
+		compatible = "smsc,usb3503";
+		reset-gpios = <&pm8916_gpios 1 GPIO_ACTIVE_LOW>;
+		initial-mode = <1>;
+	};
+
+	usb_id: usb-id {
+		compatible = "linux,extcon-usb-gpio";
+		id-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&usb_id_default>;
+		pinctrl-names = "default";
+	};
+};
+
+&blsp_i2c3 {
+	status = "okay";
+
+	eeprom@50 {
+		compatible = "atmel,24c32";
+		reg = <0x50>;
+	};
+};
+
+&blsp_i2c4 {
+	status = "okay";
+
+	adv_bridge: bridge@39 {
+		compatible = "adi,adv7533";
+		reg = <0x39>;
+		interrupts-extended = <&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+
+		adi,dsi-lanes = <4>;
+		clocks = <&rpmcc RPM_SMD_BB_CLK2>;
+		clock-names = "cec";
+		pd-gpios = <&tlmm 32 GPIO_ACTIVE_HIGH>;
+
+		avdd-supply = <&pm8916_l6>;
+		a2vdd-supply = <&pm8916_l6>;
+		dvdd-supply = <&pm8916_l6>;
+		pvdd-supply = <&pm8916_l6>;
+		v1p2-supply = <&pm8916_l6>;
+		v3p3-supply = <&pm8916_l17>;
+
+		pinctrl-0 = <&adv7533_int_active &adv7533_switch_active>;
+		pinctrl-1 = <&adv7533_int_suspend &adv7533_switch_suspend>;
+		pinctrl-names = "default","sleep";
+		#sound-dai-cells = <0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				adv7533_in: endpoint {
+					remote-endpoint = <&mdss_dsi0_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				adv7533_out: endpoint {
+					remote-endpoint = <&hdmi_con>;
+				};
+			};
+		};
+	};
+};
+
+&blsp_i2c6 {
+	status = "okay";
+
+	rtc@30 {
+		compatible = "sii,s35390a";
+		reg = <0x30>;
+	};
+
+	eeprom@50 {
+		compatible = "atmel,24c256";
+		reg = <0x50>;
+	};
+};
+
+&blsp_spi5 {
+	cs-gpios = <&tlmm 18 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	tpm@0 {
+		compatible = "infineon,slb9670", "tcg,tpm_tis-spi";
+		reg = <0>;
+		spi-max-frequency = <500000>;
+	};
+};
+
+&blsp_uart1 {
+	label = "UART0";
+	status = "okay";
+};
+
+&blsp_uart2 {
+	label = "UART1";
+	status = "okay";
+};
+
+&lpass {
+	status = "okay";
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dsi0_out {
+	data-lanes = <0 1 2 3>;
+	remote-endpoint = <&adv7533_in>;
+};
+
+&pm8916_codec {
+	qcom,mbhc-vthreshold-low = <75 150 237 450 500>;
+	qcom,mbhc-vthreshold-high = <75 150 237 450 500>;
+	status = "okay";
+};
+
+&pm8916_gpios {
+	gpio-line-names =
+		"USB_HUB_RESET_N_PM",
+		"USB_SW_SEL_PM",
+		"NC",
+		"NC";
+
+	usb_hub_reset_pm: usb-hub-reset-pm-state {
+		pins = "gpio1";
+		function = PMIC_GPIO_FUNC_NORMAL;
+		input-disable;
+		output-high;
+	};
+
+	usb_hub_reset_pm_device: usb-hub-reset-pm-device-state {
+		pins = "gpio1";
+		function = PMIC_GPIO_FUNC_NORMAL;
+		input-disable;
+		output-low;
+	};
+
+	usb_sw_sel_pm: usb-sw-sel-pm-state {
+		pins = "gpio2";
+		function = PMIC_GPIO_FUNC_NORMAL;
+		power-source = <PM8916_GPIO_VPH>;
+		input-disable;
+		output-high;
+	};
+
+	usb_sw_sel_pm_device: usb-sw-sel-pm-device-state {
+		pins = "gpio2";
+		function = PMIC_GPIO_FUNC_NORMAL;
+		power-source = <PM8916_GPIO_VPH>;
+		input-disable;
+		output-low;
+	};
+};
+
+&pm8916_mpps {
+	gpio-line-names =
+		"NC",
+		"WLAN_LED_CTRL",
+		"BT_LED_CTRL",
+		"NC";
+
+	pm8916_mpps_leds: pm8916-mpps-state {
+		pins = "mpp2", "mpp3";
+		function = "digital";
+		output-low;
+	};
+};
+
+&pm8916_resin {
+	linux,code = <KEY_POWER>;
+	status = "okay";
+};
+
+&pm8916_rpm_regulators {
+	pm8916_l17: l17 {
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+};
+
+&sdhc_1 {
+	status = "okay";
+};
+
+&sdhc_2 {
+	pinctrl-0 = <&sdc2_default &sdc2_cd_default>;
+	pinctrl-1 = <&sdc2_sleep &sdc2_cd_default>;
+	pinctrl-names = "default", "sleep";
+	cd-gpios = <&tlmm 38 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
+&sound {
+	pinctrl-0 = <&cdc_pdm_default &sec_mi2s_default>;
+	pinctrl-1 = <&cdc_pdm_sleep &sec_mi2s_sleep>;
+	pinctrl-names = "default", "sleep";
+	model = "HMIBSC";
+	audio-routing =
+		"AMIC2", "MIC BIAS Internal2",
+		"AMIC3", "MIC BIAS External1";
+	status = "okay";
+
+	quaternary-dai-link {
+		link-name = "ADV7533";
+		cpu {
+			sound-dai = <&lpass MI2S_QUATERNARY>;
+		};
+		codec {
+			sound-dai = <&adv_bridge 0>;
+		};
+	};
+
+	primary-dai-link {
+		link-name = "WCD";
+		cpu {
+			sound-dai = <&lpass MI2S_PRIMARY>;
+		};
+		codec {
+			sound-dai = <&lpass_codec 0>, <&pm8916_codec 0>;
+		};
+	};
+
+	tertiary-dai-link {
+		link-name = "WCD-Capture";
+		cpu {
+			sound-dai = <&lpass MI2S_TERTIARY>;
+		};
+		codec {
+			sound-dai = <&lpass_codec 1>, <&pm8916_codec 1>;
+		};
+	};
+};
+
+&tlmm {
+	pinctrl-0 = <&uart1_mux0_rs232_high &uart1_mux1_rs232_low>;
+	pinctrl-names = "default";
+
+	adv7533_int_active: adv533-int-active-state {
+		pins = "gpio31";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+	};
+
+	adv7533_int_suspend: adv7533-int-suspend-state {
+		pins = "gpio31";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	adv7533_switch_active: adv7533-switch-active-state {
+		pins = "gpio32";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+	};
+
+	adv7533_switch_suspend: adv7533-switch-suspend-state {
+		pins = "gpio32";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	msm_key_volp_n_default: msm-key-volp-n-default-state {
+		pins = "gpio107";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-up;
+	};
+
+	sdc2_cd_default: sdc2-cd-default-state {
+		pins = "gpio38";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	/*
+	 * UART1 being the debug console supports various modes of
+	 * operation (RS-232/485/422) controlled via GPIOs configured
+	 * mux as follows:
+	 *
+	 *   gpio100    gpio99    UART mode
+	 *   0          0         loopback
+	 *   0          1         RS-232
+	 *   1          0         RS-485
+	 *   1          1         RS-422
+	 *
+	 * The default mode configured here is RS-232 mode.
+	 */
+	uart1_mux0_rs232_high: uart1-mux0-rs232-state {
+		bootph-all;
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+		output-high;
+	};
+
+	uart1_mux1_rs232_low: uart1-mux1-rs232-state {
+		bootph-all;
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+		output-low;
+	};
+
+	usb_id_default: usb-id-default-state {
+		pins = "gpio110";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-up;
+	};
+};
+
+&usb {
+	extcon = <&usb_id>, <&usb_id>;
+	pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>;
+	pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>;
+	pinctrl-names = "default", "device";
+	status = "okay";
+};
+
+&usb_hs_phy {
+	extcon = <&usb_id>;
+};
+
+&wcnss {
+	firmware-name = "qcom/apq8016/wcnss.mbn";
+	status = "okay";
+};
+
+&wcnss_ctrl {
+	firmware-name = "qcom/apq8016/WCNSS_qcom_wlan_nv_sbc.bin";
+};
+
+&wcnss_iris {
+	compatible = "qcom,wcn3620";
+};
+
+&wcnss_mem {
+	status = "okay";
+};
+
+/* PINCTRL - additions to nodes defined in msm8916.dtsi */
+
+/*
+ * 2mA drive strength is not enough when connecting multiple
+ * I2C devices with different pull up resistors.
+ */
+&blsp_i2c4_default {
+	drive-strength = <16>;
+};
+
+&blsp_i2c6_default {
+	drive-strength = <16>;
+};
+
+&blsp_uart1_default {
+	bootph-all;
+};
+
+/* Enable CoreSight */
+&cti0 { status = "okay"; };
+&cti1 { status = "okay"; };
+&cti12 { status = "okay"; };
+&cti13 { status = "okay"; };
+&cti14 { status = "okay"; };
+&cti15 { status = "okay"; };
+&debug0 { status = "okay"; };
+&debug1 { status = "okay"; };
+&debug2 { status = "okay"; };
+&debug3 { status = "okay"; };
+&etf { status = "okay"; };
+&etm0 { status = "okay"; };
+&etm1 { status = "okay"; };
+&etm2 { status = "okay"; };
+&etm3 { status = "okay"; };
+&etr { status = "okay"; };
+&funnel0 { status = "okay"; };
+&funnel1 { status = "okay"; };
+&replicator { status = "okay"; };
+&stm { status = "okay"; };
+&tpiu { status = "okay"; };
-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 2/3] dt-bindings: arm: qcom: Add Schneider Electric HMIBSC board
From: Sumit Garg @ 2024-04-03  4:34 UTC (permalink / raw)
  To: linux-arm-msm, devicetree
  Cc: andersson, konrad.dybcio, robh+dt, krzysztof.kozlowski+dt,
	conor+dt, stephan, caleb.connolly, neil.armstrong,
	dmitry.baryshkov, laetitia.mariottini, pascal.eberhard,
	abdou.saker, jimmy.lalande, benjamin.missey, daniel.thompson,
	linux-kernel, Sumit Garg, Krzysztof Kozlowski
In-Reply-To: <20240403043416.3800259-1-sumit.garg@linaro.org>

Document the compatible for the Schneider Electric HMIBSC IIoT edge box
core board based on the Qualcomm APQ8016E SoC.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 1a5fb889a444..c8c91754fe04 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -137,6 +137,7 @@ properties:
       - items:
           - enum:
               - qcom,apq8016-sbc
+              - schneider,apq8016-hmibsc
           - const: qcom,apq8016
 
       - items:
-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 1/3] dt-bindings: vendor-prefixes: Add Schneider Electric
From: Sumit Garg @ 2024-04-03  4:34 UTC (permalink / raw)
  To: linux-arm-msm, devicetree
  Cc: andersson, konrad.dybcio, robh+dt, krzysztof.kozlowski+dt,
	conor+dt, stephan, caleb.connolly, neil.armstrong,
	dmitry.baryshkov, laetitia.mariottini, pascal.eberhard,
	abdou.saker, jimmy.lalande, benjamin.missey, daniel.thompson,
	linux-kernel, Sumit Garg, Krzysztof Kozlowski
In-Reply-To: <20240403043416.3800259-1-sumit.garg@linaro.org>

Add vendor prefix for Schneider Electric (https://www.se.com/).

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 1a0dc04f1db4..4ef38573e411 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1211,6 +1211,8 @@ patternProperties:
     description: Smart Battery System
   "^schindler,.*":
     description: Schindler
+  "^schneider,.*":
+    description: Schneider Electric
   "^seagate,.*":
     description: Seagate Technology PLC
   "^seeed,.*":
-- 
2.34.1


^ permalink raw reply related

* [PATCH v5 0/3] arm64: dts: qcom: apq8016: Add Schneider HMIBSC board DTS
From: Sumit Garg @ 2024-04-03  4:34 UTC (permalink / raw)
  To: linux-arm-msm, devicetree
  Cc: andersson, konrad.dybcio, robh+dt, krzysztof.kozlowski+dt,
	conor+dt, stephan, caleb.connolly, neil.armstrong,
	dmitry.baryshkov, laetitia.mariottini, pascal.eberhard,
	abdou.saker, jimmy.lalande, benjamin.missey, daniel.thompson,
	linux-kernel, Sumit Garg

Add Schneider Electric HMIBSC board DTS. The HMIBSC board is an IIoT Edge
Box Core board based on the Qualcomm APQ8016E SoC. For more information
refer to the product page [1].

One of the major difference from db410c is serial port where HMIBSC board
uses UART1 as the debug console with a default RS232 mode (UART1 mode mux
configured via gpio99 and gpio100).

Support for Schneider Electric HMIBSC. Features:
- Qualcomm Snapdragon 410C SoC - APQ8016 (4xCortex A53, Adreno 306)
- 1GiB RAM
- 8GiB eMMC, SD slot
- WiFi and Bluetooth
- 2x Host, 1x Device USB port
- HDMI
- Discrete TPM2 chip over SPI
- USB ethernet adaptors (soldered)

This series is a v2 since v1 of this DTS file has been reviewed on the
U-Boot mailing list [2].

Changes in v5:
- Addressed another nitpick from Stephen.
- Collected Stephen's review tag.
- Warnings reported by Rob's DT check bot aren't related to HMIBSC
  board DTS but rather they are due to msm8916.dtsi or extcon-usb-gpio.txt
  still not converted to YAML format.

Changes in v4:
- Dropped IRQ_TYPE_EDGE_FALLING for pm8916_resin given the expectations
  of Linux kernel driver. Instead depend on systemd workaround suggested
  by Caleb to get expected HMIBSC reset behaviour.
- Incorporated further DT coding style comments from Stephen.
- Warnings reported by Rob's DT check bot aren't related to HMIBSC
  board DTS but rather they are due to msm8916.dtsi or extcon-usb-gpio.txt
  still not converted to YAML format.

Changes in v3:
- Picked up tags.
- Fixed further DT schema warnings.
- Configure resin/power button interrupt as falling edge.
- Incorporate DTS coding style comments from Krzysztof and Konrad.

Changes in v2:
- Fix DT schema warnings.
- Incorporate suggestions from Stephan.
- Document UART1 mode GPIOs based mux.

[1] https://www.se.com/us/en/product/HMIBSCEA53D1L0T/iiot-edge-box-core-harmony-ipc-emmc-dc-linux-tpm/
[2] https://patchwork.ozlabs.org/project/uboot/patch/20240311111027.44577-6-sumit.garg@linaro.org/

Sumit Garg (3):
  dt-bindings: vendor-prefixes: Add Schneider Electric
  dt-bindings: arm: qcom: Add Schneider Electric HMIBSC board
  arm64: dts: qcom: apq8016: Add Schneider HMIBSC board DTS

 .../devicetree/bindings/arm/qcom.yaml         |   1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm64/boot/dts/qcom/Makefile             |   1 +
 .../dts/qcom/apq8016-schneider-hmibsc.dts     | 491 ++++++++++++++++++
 4 files changed, 495 insertions(+)
 create mode 100644 arch/arm64/boot/dts/qcom/apq8016-schneider-hmibsc.dts

-- 
2.34.1


^ permalink raw reply

* Re: [PATCH v1 2/2] media: i2c: Add GC05A2 image sensor driver
From: Zhi Mao (毛智) @ 2024-04-03  4:24 UTC (permalink / raw)
  To: sakari.ailus@linux.intel.com
  Cc: heiko@sntech.de, gerald.loacker@wolfvision.net,
	robh+dt@kernel.org, yunkec@chromium.org,
	linux-kernel@vger.kernel.org, dan.scally@ideasonboard.com,
	linux-media@vger.kernel.org,
	Shengnan Wang (王圣男), hdegoede@redhat.com,
	linus.walleij@linaro.org, andy.shevchenko@gmail.com,
	Yaya Chang (張雅清), mchehab@kernel.org,
	jacopo.mondi@ideasonboard.com, jernej.skrabec@gmail.com,
	linux-mediatek@lists.infradead.org, bingbu.cao@intel.com,
	Project_Global_Chrome_Upstream_Group, conor+dt@kernel.org,
	10572168@qq.com, hverkuil-cisco@xs4all.nl,
	tomi.valkeinen@ideasonboard.com,
	krzysztof.kozlowski+dt@linaro.org,
	linux-arm-kernel@lists.infradead.org, matthias.bgg@gmail.com,
	laurent.pinchart@ideasonboard.com, devicetree@vger.kernel.org,
	angelogioacchino.delregno@collabora.com, macromorgan@hotmail.com
In-Reply-To: <8a6bbbdde57283b5bf8cab0ea7ecb0f201d437e7.camel@mediatek.com>

Hi Sakari,

Update gc05a2 driver patch.

On Sat, 2024-03-23 at 10:59 +0800, zhi.mao@mediatek.com wrote:
> Hi Sakari,
> 
> Thanks for your review.
> 
> On Wed, 2024-03-20 at 07:29 +0000, Sakari Ailus wrote:
> >  	 
> > External email : Please do not click links or open attachments
> > until
> > you have verified the sender or the content.
> >  Hi Zhi,
> > 
> > Thanks for the set.
> > 
> > On Sat, Mar 16, 2024 at 10:52:53AM +0800, Zhi Mao wrote:
> > > +static int gc05a2_set_ctrl(struct v4l2_ctrl *ctrl)
> > > +{
> > > +struct gc05a2 *gc05a2 =
> > > +container_of(ctrl->handler, struct gc05a2, ctrls);
> > > +int ret = 0;
> > > +s64 exposure_max;
> > > +struct v4l2_subdev_state *state;
> > > +const struct v4l2_mbus_framefmt *format;
> > > +
> > > +state = v4l2_subdev_get_locked_active_state(&gc05a2->sd);
> > > +format = v4l2_subdev_state_get_format(state, 0);
> > > +
> > > +if (ctrl->id == V4L2_CID_VBLANK) {
> > > +/* Update max exposure while meeting expected vblanking */
> > > +exposure_max = format->height + ctrl->val - GC05A2_EXP_MARGIN;
> > > +__v4l2_ctrl_modify_range(gc05a2->exposure,
> > > + gc05a2->exposure->minimum,
> > > + exposure_max, gc05a2->exposure->step,
> > > + exposure_max);
> > > +}
> > > +
> > > +/*
> > > + * Applying V4L2 control value only happens
> > > + * when power is on for streaming.
> > > + */
> > > +if (!pm_runtime_get_if_in_use(gc05a2->dev))
> > 
> > This should be pm_runtime_get_if_active(). Please assume it takes a
> > single
> > argument (the device)---see commit
> > c0ef3df8dbaef51ee4cfd58a471adf2eaee6f6b3.
> > 
> > The same comment applies to the GC08A3 if it uses autosuspend,
> > please
> > post
> > a new patch for that.
> > 
> 
> fixed, patch as below: 
> gc05a patch:v2 
> 
> 
https://lore.kernel.org/linux-media/20240323014751.4989-1-zhi.mao@mediatek.com/
> 

gc05a driver was updated to patch:v3

https://lore.kernel.org/linux-media/20240403033825.9072-1-zhi.mao@mediatek.com/


> gc08a patch:v8
> 
> 
https://lore.kernel.org/linux-media/20240323023851.5503-1-zhi.mao@mediatek.com/
> 
> > -- 
> > Kind regards,
> > 
> > Sakari Ailus

^ permalink raw reply

* Re: [PATCH] arm64: dts: qcom: qcm6490-idp: Add change to name the regulators
From: Bjorn Andersson @ 2024-04-03  3:52 UTC (permalink / raw)
  To: Umang Chheda, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, linux-arm-msm, devicetree, linux-kernel,
	quic_kamalw
In-Reply-To: <20240329140534820-0700.eberman@hu-eberman-lv.qualcomm.com>

On Fri, Mar 29, 2024 at 02:09:55PM -0700, Elliot Berman wrote:
> Nit: the subject line should be:
> 
> arm64: dts: qcom: qcm6490: Name the regulators
> 

Much cleaner subject, but no longer matches file prefix.

> I don't know if it merits a resend, though.

Yes, please.

Regards,
Bjorn

^ permalink raw reply

* Re: [PATCH 1/3] media: mediatek: vcodec: fix h264 multi statless decoder smatch warning
From: Yunfei Dong (董云飞) @ 2024-04-03  3:45 UTC (permalink / raw)
  To: nhebert@chromium.org, benjamin.gaignard@collabora.com,
	nfraprado@collabora.com, angelogioacchino.delregno@collabora.com,
	nicolas.dufresne@collabora.com, hverkuil-cisco@xs4all.nl
  Cc: linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org,
	frkoenig@chromium.org, stevecho@chromium.org,
	linux-media@vger.kernel.org, devicetree@vger.kernel.org,
	daniel@ffwll.ch, Project_Global_Chrome_Upstream_Group,
	hsinyi@chromium.org, linux-arm-kernel@lists.infradead.org
In-Reply-To: <4949bd54-8c32-4490-ab19-d38796d29ac1@collabora.com>

Hi AngeloGioacchino,

Thanks for your reviewing.
On Tue, 2024-04-02 at 11:50 +0200, AngeloGioacchino Del Regno wrote:
> Il 29/02/24 10:56, Yunfei Dong ha scritto:
> > Fix smatch static checker warning for vdec_h264_req_multi_if.c.
> > Leading to kernel crash when fb is NULL.
> > 
> > Fixes: 397edc703a10 ("media: mediatek: vcodec: add h264 decoder")
> > Signed-off-by: Yunfei Dong <yunfei.dong@mediatek.com>
> > ---
> >   .../vcodec/decoder/vdec/vdec_h264_req_multi_if.c         | 9
> > +++++++--
> >   1 file changed, 7 insertions(+), 2 deletions(-)
> > 
> > diff --git
> > a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > index 0e741e0dc8ba..ab8e708e0df1 100644
> > ---
> > a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > +++
> > b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req
> > _multi_if.c
> > @@ -724,11 +724,16 @@ static int vdec_h264_slice_single_decode(void
> > *h_vdec, struct mtk_vcodec_mem *bs
> >   		return vpu_dec_reset(vpu);
> >   
> >   	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
> > +	if (!fb) {
> > +		mtk_vdec_err(inst->ctx, "fb buffer is NULL");
> > +		return -EBUSY;
> > +	}
> > +
> >   	src_buf_info = container_of(bs, struct mtk_video_dec_buf,
> > bs_buffer);
> >   	dst_buf_info = container_of(fb, struct mtk_video_dec_buf,
> > frame_buffer);
> >   
> > -	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
> > -	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
> 
> You're changing the behavior here, can you please explain why this
> change is valid
> into the commit description?
> 
The driver already add the condition to check whether fb is NULL at the
front, no need these two lines again.

> Thanks,
> Angelo
> 
Best Regards,
Yunfei Dong
> > +	y_fb_dma = (u64)fb->base_y.dma_addr;
> > +	c_fb_dma = (u64)fb->base_c.dma_addr;
> >   	mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx
> > c_dma=%llx",
> >   		       inst->ctx->decoded_frame_cnt, y_fb_dma,
> > c_fb_dma);
> >   
> 
> 
> 

^ permalink raw reply

* [PATCH v4 4/4] drm: panel: Add LG sw43408 panel driver
From: Dmitry Baryshkov @ 2024-04-03  3:43 UTC (permalink / raw)
  To: Sumit Semwal, Caleb Connolly, Neil Armstrong, Jessica Zhang,
	Sam Ravnborg, David Airlie, Daniel Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: dri-devel, devicetree, linux-kernel, linux-arm-msm, Vinod Koul,
	Caleb Connolly, Marijn Suijten
In-Reply-To: <20240403-lg-sw43408-panel-v4-0-a386d5d3b0c6@linaro.org>

From: Sumit Semwal <sumit.semwal@linaro.org>

LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel, used in some Pixel3
phones.

Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
[vinod: Add DSC support]
Signed-off-by: Vinod Koul <vkoul@kernel.org>
[caleb: cleanup and support turning off the panel]
Signed-off-by: Caleb Connolly <caleb@connolly.tech>
[DB: partially rewrote the driver and fixed DSC programming]
Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 MAINTAINERS                              |   8 +
 drivers/gpu/drm/panel/Kconfig            |  11 ++
 drivers/gpu/drm/panel/Makefile           |   1 +
 drivers/gpu/drm/panel/panel-lg-sw43408.c | 323 +++++++++++++++++++++++++++++++
 4 files changed, 343 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d36c19c1bf81..4cc43c16e07e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6789,6 +6789,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/display/panel/jadard,jd9365da-h3.yaml
 F:	drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
 
+DRM DRIVER FOR LG SW43408 PANELS
+M:	Sumit Semwal <sumit.semwal@linaro.org>
+M:	Caleb Connolly <caleb.connolly@linaro.org>
+S:	Maintained
+T:	git git://anongit.freedesktop.org/drm/drm-misc
+F:	Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml
+F:	drivers/gpu/drm/panel/panel-lg-sw43408.c
+
 DRM DRIVER FOR LOGICVC DISPLAY CONTROLLER
 M:	Paul Kocialkowski <paul.kocialkowski@bootlin.com>
 S:	Supported
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 6dc451f58a3e..a55e9437c8cf 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -335,6 +335,17 @@ config DRM_PANEL_LG_LG4573
 	  Say Y here if you want to enable support for LG4573 RGB panel.
 	  To compile this driver as a module, choose M here.
 
+config DRM_PANEL_LG_SW43408
+	tristate "LG SW43408 panel"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  Say Y here if you want to enable support for LG sw43408 panel.
+	  The panel has a 1080x2160 resolution and uses
+	  24 bit RGB per pixel. It provides a MIPI DSI interface to
+	  the host and has a built-in LED backlight.
+
 config DRM_PANEL_MAGNACHIP_D53E6EA8966
 	tristate "Magnachip D53E6EA8966 DSI panel"
 	depends on OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 24a02655d726..0b40b010e8e7 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o
 obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
+obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o
 obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
 obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o
diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c b/drivers/gpu/drm/panel/panel-lg-sw43408.c
new file mode 100644
index 000000000000..6fcdaa5cf6c5
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019-2024 Linaro Ltd
+ * Author: Sumit Semwal <sumit.semwal@linaro.org>
+ *	 Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dsc_helper.h>
+
+#define NUM_SUPPLIES 2
+
+struct sw43408_panel {
+	struct drm_panel base;
+	struct mipi_dsi_device *link;
+
+	struct regulator_bulk_data supplies[NUM_SUPPLIES];
+
+	struct gpio_desc *reset_gpio;
+
+	struct drm_dsc_config dsc;
+};
+
+static inline struct sw43408_panel *to_panel_info(struct drm_panel *panel)
+{
+	return container_of(panel, struct sw43408_panel, base);
+}
+
+static int sw43408_unprepare(struct drm_panel *panel)
+{
+	struct sw43408_panel *ctx = to_panel_info(panel);
+	int ret;
+
+	ret = mipi_dsi_dcs_set_display_off(ctx->link);
+	if (ret < 0)
+		dev_err(panel->dev, "set_display_off cmd failed ret = %d\n", ret);
+
+	ret = mipi_dsi_dcs_enter_sleep_mode(ctx->link);
+	if (ret < 0)
+		dev_err(panel->dev, "enter_sleep cmd failed ret = %d\n", ret);
+
+	msleep(100);
+
+	gpiod_set_value(ctx->reset_gpio, 1);
+
+	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+}
+
+static int sw43408_program(struct drm_panel *panel)
+{
+	struct sw43408_panel *ctx = to_panel_info(panel);
+	struct drm_dsc_picture_parameter_set pps;
+
+	mipi_dsi_dcs_write_seq(ctx->link, MIPI_DCS_SET_GAMMA_CURVE, 0x02);
+
+	mipi_dsi_dcs_set_tear_on(ctx->link, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+
+	mipi_dsi_dcs_write_seq(ctx->link, 0x53, 0x0c, 0x30);
+	mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x00, 0x70, 0xdf, 0x00, 0x70, 0xdf);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xf7, 0x01, 0x49, 0x0c);
+
+	mipi_dsi_dcs_exit_sleep_mode(ctx->link);
+
+	msleep(135);
+
+	/* COMPRESSION_MODE moved after setting the PPS */
+
+	mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xac);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xe5,
+			       0x00, 0x3a, 0x00, 0x3a, 0x00, 0x0e, 0x10);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xb5,
+			       0x75, 0x60, 0x2d, 0x5d, 0x80, 0x00, 0x0a, 0x0b,
+			       0x00, 0x05, 0x0b, 0x00, 0x80, 0x0d, 0x0e, 0x40,
+			       0x00, 0x0c, 0x00, 0x16, 0x00, 0xb8, 0x00, 0x80,
+			       0x0d, 0x0e, 0x40, 0x00, 0x0c, 0x00, 0x16, 0x00,
+			       0xb8, 0x00, 0x81, 0x00, 0x03, 0x03, 0x03, 0x01,
+			       0x01);
+	msleep(85);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xcd,
+			       0x00, 0x00, 0x00, 0x19, 0x19, 0x19, 0x19, 0x19,
+			       0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
+			       0x16, 0x16);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xcb, 0x80, 0x5c, 0x07, 0x03, 0x28);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xc0, 0x02, 0x02, 0x0f);
+	mipi_dsi_dcs_write_seq(ctx->link, 0x55, 0x04, 0x61, 0xdb, 0x04, 0x70, 0xdb);
+	mipi_dsi_dcs_write_seq(ctx->link, 0xb0, 0xca);
+
+	mipi_dsi_dcs_set_display_on(ctx->link);
+
+	msleep(50);
+
+	ctx->link->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+	drm_dsc_pps_payload_pack(&pps, ctx->link->dsc);
+	mipi_dsi_picture_parameter_set(ctx->link, &pps);
+
+	ctx->link->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	/*
+	 * This panel uses PPS selectors with offset:
+	 * PPS 1 if pps_identifier is 0
+	 * PPS 2 if pps_identifier is 1
+	 */
+	mipi_dsi_compression_mode_ext(ctx->link, true,
+				      MIPI_DSI_COMPRESSION_DSC, 1);
+
+
+	return 0;
+}
+
+static int sw43408_prepare(struct drm_panel *panel)
+{
+	struct sw43408_panel *ctx = to_panel_info(panel);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	usleep_range(5000, 6000);
+
+	gpiod_set_value(ctx->reset_gpio, 0);
+	usleep_range(9000, 10000);
+	gpiod_set_value(ctx->reset_gpio, 1);
+	usleep_range(1000, 2000);
+	gpiod_set_value(ctx->reset_gpio, 0);
+	usleep_range(9000, 10000);
+
+	ret = sw43408_program(panel);
+	if (ret)
+		goto poweroff;
+
+	return 0;
+
+poweroff:
+	gpiod_set_value(ctx->reset_gpio, 1);
+	regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	return ret;
+}
+
+static const struct drm_display_mode sw43408_mode = {
+	.clock = (1080 + 20 + 32 + 20) * (2160 + 20 + 4 + 20) * 60 / 1000,
+
+	.hdisplay = 1080,
+	.hsync_start = 1080 + 20,
+	.hsync_end = 1080 + 20 + 32,
+	.htotal = 1080 + 20 + 32 + 20,
+
+	.vdisplay = 2160,
+	.vsync_start = 2160 + 20,
+	.vsync_end = 2160 + 20 + 4,
+	.vtotal = 2160 + 20 + 4 + 20,
+
+	.width_mm = 62,
+	.height_mm = 124,
+
+	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static int sw43408_get_modes(struct drm_panel *panel,
+			      struct drm_connector *connector)
+{
+	return drm_connector_helper_get_modes_fixed(connector, &sw43408_mode);
+}
+
+static int sw43408_backlight_update_status(struct backlight_device *bl)
+{
+	struct mipi_dsi_device *dsi = bl_get_data(bl);
+	uint16_t brightness = backlight_get_brightness(bl);
+
+	return mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+}
+
+const struct backlight_ops sw43408_backlight_ops = {
+	.update_status = sw43408_backlight_update_status,
+};
+
+static int sw43408_backlight_init(struct sw43408_panel *ctx)
+{
+	struct device *dev = &ctx->link->dev;
+	const struct backlight_properties props = {
+		.type = BACKLIGHT_PLATFORM,
+		.brightness = 255,
+		.max_brightness = 255,
+	};
+
+	ctx->base.backlight = devm_backlight_device_register(dev, dev_name(dev), dev,
+							ctx->link,
+							&sw43408_backlight_ops,
+							&props);
+
+	if (IS_ERR(ctx->base.backlight))
+		return dev_err_probe(dev, PTR_ERR(ctx->base.backlight),
+				     "Failed to create backlight\n");
+
+	return 0;
+}
+
+static const struct drm_panel_funcs sw43408_funcs = {
+	.unprepare = sw43408_unprepare,
+	.prepare = sw43408_prepare,
+	.get_modes = sw43408_get_modes,
+};
+
+static const struct of_device_id sw43408_of_match[] = {
+	{ .compatible = "lg,sw43408", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sw43408_of_match);
+
+static int sw43408_add(struct sw43408_panel *ctx)
+{
+	struct device *dev = &ctx->link->dev;
+	int ret;
+
+	ctx->supplies[0].supply = "vddi"; /* 1.88 V */
+	ctx->supplies[0].init_load_uA = 62000;
+	ctx->supplies[1].supply = "vpnl"; /* 3.0 V */
+	ctx->supplies[1].init_load_uA = 857000;
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+				      ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->reset_gpio)) {
+		dev_err(dev, "cannot get reset gpio %ld\n",
+			      PTR_ERR(ctx->reset_gpio));
+		return PTR_ERR(ctx->reset_gpio);
+	}
+
+	ret = sw43408_backlight_init(ctx);
+	if (ret < 0)
+		return ret;
+
+	ctx->base.prepare_prev_first = true;
+
+	drm_panel_init(&ctx->base, dev, &sw43408_funcs, DRM_MODE_CONNECTOR_DSI);
+
+	drm_panel_add(&ctx->base);
+	return ret;
+}
+
+static int sw43408_probe(struct mipi_dsi_device *dsi)
+{
+	struct sw43408_panel *ctx;
+	int ret;
+
+	ctx = devm_kzalloc(&dsi->dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	dsi->mode_flags = MIPI_DSI_MODE_LPM;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->lanes = 4;
+
+	ctx->link = dsi;
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	ret = sw43408_add(ctx);
+	if (ret < 0)
+		return ret;
+
+	/* The panel is DSC panel only, set the dsc params */
+	ctx->dsc.dsc_version_major = 0x1;
+	ctx->dsc.dsc_version_minor = 0x1;
+
+	/* slice_count * slice_width == width */
+	ctx->dsc.slice_height = 16;
+	ctx->dsc.slice_width = 540;
+	ctx->dsc.slice_count = 2;
+	ctx->dsc.bits_per_component = 8;
+	ctx->dsc.bits_per_pixel = 8 << 4;
+	ctx->dsc.block_pred_enable = true;
+
+	dsi->dsc = &ctx->dsc;
+
+	return mipi_dsi_attach(dsi);
+}
+
+static void sw43408_remove(struct mipi_dsi_device *dsi)
+{
+	struct sw43408_panel *ctx = mipi_dsi_get_drvdata(dsi);
+	int ret;
+
+	ret = sw43408_unprepare(&ctx->base);
+	if (ret < 0)
+		dev_err(&dsi->dev, "failed to unprepare panel: %d\n",
+			      ret);
+
+	ret = mipi_dsi_detach(dsi);
+	if (ret < 0)
+		dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
+
+	drm_panel_remove(&ctx->base);
+}
+
+static struct mipi_dsi_driver sw43408_driver = {
+	.driver = {
+		.name = "panel-lg-sw43408",
+		.of_match_table = sw43408_of_match,
+	},
+	.probe = sw43408_probe,
+	.remove = sw43408_remove,
+};
+module_mipi_dsi_driver(sw43408_driver);
+
+MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
+MODULE_DESCRIPTION("LG SW436408 MIPI-DSI LED panel");
+MODULE_LICENSE("GPL");

-- 
2.39.2


^ permalink raw reply related

* [PATCH v4 3/4] drm/mipi-dsi: add mipi_dsi_compression_mode_ext()
From: Dmitry Baryshkov @ 2024-04-03  3:43 UTC (permalink / raw)
  To: Sumit Semwal, Caleb Connolly, Neil Armstrong, Jessica Zhang,
	Sam Ravnborg, David Airlie, Daniel Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: dri-devel, devicetree, linux-kernel, linux-arm-msm
In-Reply-To: <20240403-lg-sw43408-panel-v4-0-a386d5d3b0c6@linaro.org>

Add the extended version of mipi_dsi_compression_mode(). It provides
a way to specify the algorithm and PPS selector.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 41 ++++++++++++++++++++++++++++++++++-------
 include/drm/drm_mipi_dsi.h     |  9 +++++++++
 2 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index 9874ff6d4718..795001bb7ff1 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -645,29 +645,56 @@ int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
 EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
 
 /**
- * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
+ * mipi_dsi_compression_mode_ext() - enable/disable DSC on the peripheral
  * @dsi: DSI peripheral device
  * @enable: Whether to enable or disable the DSC
+ * @algo: Selected compression algorithm
+ * @pps_selector: Select PPS from the table of pre-stored or uploaded PPS entries
  *
- * Enable or disable Display Stream Compression on the peripheral using the
- * default Picture Parameter Set and VESA DSC 1.1 algorithm.
+ * Enable or disable Display Stream Compression on the peripheral.
  *
  * Return: 0 on success or a negative error code on failure.
  */
-int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
+int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
+				  enum mipi_dsi_compression_algo algo,
+				  unsigned int pps_selector)
 {
-	/* Note: Needs updating for non-default PPS or algorithm */
-	u8 tx[2] = { enable << 0, 0 };
+	u8 tx[2] = { };
 	struct mipi_dsi_msg msg = {
 		.channel = dsi->channel,
 		.type = MIPI_DSI_COMPRESSION_MODE,
 		.tx_len = sizeof(tx),
 		.tx_buf = tx,
 	};
-	int ret = mipi_dsi_device_transfer(dsi, &msg);
+	int ret;
+
+	if (algo > 3 || pps_selector > 3)
+		return -EINVAL;
+
+	tx[0] = (enable << 0) |
+		(algo << 1) |
+		(pps_selector << 4);
+
+	ret = mipi_dsi_device_transfer(dsi, &msg);
 
 	return (ret < 0) ? ret : 0;
 }
+EXPORT_SYMBOL(mipi_dsi_compression_mode_ext);
+
+/**
+ * mipi_dsi_compression_mode() - enable/disable DSC on the peripheral
+ * @dsi: DSI peripheral device
+ * @enable: Whether to enable or disable the DSC
+ *
+ * Enable or disable Display Stream Compression on the peripheral using the
+ * default Picture Parameter Set and VESA DSC 1.1 algorithm.
+ *
+ * Return: 0 on success or a negative error code on failure.
+ */
+int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
+{
+	return mipi_dsi_compression_mode_ext(dsi, enable, MIPI_DSI_COMPRESSION_DSC, 0);
+}
 EXPORT_SYMBOL(mipi_dsi_compression_mode);
 
 /**
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 3011d33eccbd..82b1cc434ea3 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -226,6 +226,12 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt)
 	return -EINVAL;
 }
 
+enum mipi_dsi_compression_algo {
+	MIPI_DSI_COMPRESSION_DSC = 0,
+	MIPI_DSI_COMPRESSION_VENDOR = 3,
+	/* other two values are reserved, DSI 1.3 */
+};
+
 struct mipi_dsi_device *
 mipi_dsi_device_register_full(struct mipi_dsi_host *host,
 			      const struct mipi_dsi_device_info *info);
@@ -242,6 +248,9 @@ int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi);
 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
 					    u16 value);
 int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable);
+int mipi_dsi_compression_mode_ext(struct mipi_dsi_device *dsi, bool enable,
+				  enum mipi_dsi_compression_algo algo,
+				  unsigned int pps_selector);
 int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
 				   const struct drm_dsc_picture_parameter_set *pps);
 

-- 
2.39.2


^ permalink raw reply related

* [PATCH v4 2/4] drm/mipi-dsi: use correct return type for the DSC functions
From: Dmitry Baryshkov @ 2024-04-03  3:43 UTC (permalink / raw)
  To: Sumit Semwal, Caleb Connolly, Neil Armstrong, Jessica Zhang,
	Sam Ravnborg, David Airlie, Daniel Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: dri-devel, devicetree, linux-kernel, linux-arm-msm,
	Marijn Suijten
In-Reply-To: <20240403-lg-sw43408-panel-v4-0-a386d5d3b0c6@linaro.org>

The functions mipi_dsi_compression_mode() and
mipi_dsi_picture_parameter_set() return 0-or-error rather than a buffer
size. Follow example of other similar MIPI DSI functions and use int
return type instead of size_t.

Fixes: f4dea1aaa9a1 ("drm/dsi: add helpers for DSI compression mode and PPS packets")
Reviewed-by: Marijn Suijten <marijn.suijten@somainline.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/drm_mipi_dsi.c | 6 +++---
 include/drm/drm_mipi_dsi.h     | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index ef6e416522f8..9874ff6d4718 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -654,7 +654,7 @@ EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
  *
  * Return: 0 on success or a negative error code on failure.
  */
-ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
+int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
 {
 	/* Note: Needs updating for non-default PPS or algorithm */
 	u8 tx[2] = { enable << 0, 0 };
@@ -679,8 +679,8 @@ EXPORT_SYMBOL(mipi_dsi_compression_mode);
  *
  * Return: 0 on success or a negative error code on failure.
  */
-ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
-				       const struct drm_dsc_picture_parameter_set *pps)
+int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
+				   const struct drm_dsc_picture_parameter_set *pps)
 {
 	struct mipi_dsi_msg msg = {
 		.channel = dsi->channel,
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index c0aec0d4d664..3011d33eccbd 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -241,9 +241,9 @@ int mipi_dsi_shutdown_peripheral(struct mipi_dsi_device *dsi);
 int mipi_dsi_turn_on_peripheral(struct mipi_dsi_device *dsi);
 int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
 					    u16 value);
-ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable);
-ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
-				       const struct drm_dsc_picture_parameter_set *pps);
+int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable);
+int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
+				   const struct drm_dsc_picture_parameter_set *pps);
 
 ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
 			       size_t size);

-- 
2.39.2


^ permalink raw reply related

* [PATCH v4 1/4] dt-bindings: panel: Add LG SW43408 MIPI-DSI panel
From: Dmitry Baryshkov @ 2024-04-03  3:43 UTC (permalink / raw)
  To: Sumit Semwal, Caleb Connolly, Neil Armstrong, Jessica Zhang,
	Sam Ravnborg, David Airlie, Daniel Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: dri-devel, devicetree, linux-kernel, linux-arm-msm, Vinod Koul,
	Caleb Connolly, Krzysztof Kozlowski
In-Reply-To: <20240403-lg-sw43408-panel-v4-0-a386d5d3b0c6@linaro.org>

From: Sumit Semwal <sumit.semwal@linaro.org>

LG SW43408 is 1080x2160, 4-lane MIPI-DSI panel present on Google Pixel 3
phones.

Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
[caleb: convert to yaml]
Signed-off-by: Caleb Connolly <caleb@connolly.tech>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 .../bindings/display/panel/lg,sw43408.yaml         | 62 ++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml b/Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml
new file mode 100644
index 000000000000..1e08648f5bc7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/lg,sw43408.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/lg,sw43408.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: LG SW43408 1080x2160 DSI panel
+
+maintainers:
+  - Caleb Connolly <caleb.connolly@linaro.org>
+
+description:
+  This panel is used on the Pixel 3, it is a 60hz OLED panel which
+  required DSC (Display Stream Compression) and has rounded corners.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: lg,sw43408
+
+  reg: true
+  port: true
+  vddi-supply: true
+  vpnl-supply: true
+  reset-gpios: true
+
+required:
+  - compatible
+  - vddi-supply
+  - vpnl-supply
+  - reset-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "lg,sw43408";
+            reg = <0>;
+
+            vddi-supply = <&vreg_l14a_1p88>;
+            vpnl-supply = <&vreg_l28a_3p0>;
+
+            reset-gpios = <&tlmm 6 GPIO_ACTIVE_LOW>;
+
+            port {
+                endpoint {
+                    remote-endpoint = <&mdss_dsi0_out>;
+                };
+            };
+        };
+    };
+...

-- 
2.39.2


^ permalink raw reply related

* [PATCH v4 0/4] drm/panel: add support for LG SW43408 panel
From: Dmitry Baryshkov @ 2024-04-03  3:43 UTC (permalink / raw)
  To: Sumit Semwal, Caleb Connolly, Neil Armstrong, Jessica Zhang,
	Sam Ravnborg, David Airlie, Daniel Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: dri-devel, devicetree, linux-kernel, linux-arm-msm, Vinod Koul,
	Caleb Connolly, Krzysztof Kozlowski, Marijn Suijten

The LG SW43408 panel is used on Google Pixel3 devices. For a long time
we could not submit the driver, as the panel was not coming up from the
reset. The panel seems to be picky about some of the delays during init
and it also uses non-standard payload for MIPI_DSI_COMPRESSION_MODE.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
Changes in v4:
- Fix order of mipi_dsi_compression_mode_ext() args (Marijn)
- Expanded kerneldoc coments for this function (Marijn)
- And added arguments validation (Marijn)
- In the panel driver send the COMPRESSION_MODE in LPM mode like it was
  done originally
- Expanded the .clock maths to show the reason behind the value (Marijn)
- Moved the mode out of the match data (Marijn)
- Link to v3: https://lore.kernel.org/r/20240402-lg-sw43408-panel-v3-0-144f17a11a56@linaro.org

Changes in v3:
- Fixed return type of MIPI DSC functions
- Replaced mipi_dsi_compression_mode_raw() with
  mipi_dsi_compression_mode_ext() (Marijn)
- Link to v2: https://lore.kernel.org/r/20240330-lg-sw43408-panel-v2-0-293a58717b38@linaro.org

Changes in v2:
- Removed formatting char from schema (Krzysztof)
- Moved additionalProperties after required (Krzysztof)
- Added example to the schema (Krzysztof)
- Removed obsolete comment in the commit message (Marijn)
- Moved DSC params to the panel struct (Marijn)
- Changed dsc_en to be an array (Marijn)
- Added comment regiarding slice_width and slice_count (Marijn)
- Link to v1: https://lore.kernel.org/r/20240330-lg-sw43408-panel-v1-0-f5580fc9f2da@linaro.org

---
Dmitry Baryshkov (2):
      drm/mipi-dsi: use correct return type for the DSC functions
      drm/mipi-dsi: add mipi_dsi_compression_mode_ext()

Sumit Semwal (2):
      dt-bindings: panel: Add LG SW43408 MIPI-DSI panel
      drm: panel: Add LG sw43408 panel driver

 .../bindings/display/panel/lg,sw43408.yaml         |  62 ++++
 MAINTAINERS                                        |   8 +
 drivers/gpu/drm/drm_mipi_dsi.c                     |  45 ++-
 drivers/gpu/drm/panel/Kconfig                      |  11 +
 drivers/gpu/drm/panel/Makefile                     |   1 +
 drivers/gpu/drm/panel/panel-lg-sw43408.c           | 323 +++++++++++++++++++++
 include/drm/drm_mipi_dsi.h                         |  15 +-
 7 files changed, 453 insertions(+), 12 deletions(-)
---
base-commit: a6bd6c9333397f5a0e2667d4d82fef8c970108f2
change-id: 20240330-lg-sw43408-panel-b552f411c53e

Best regards,
-- 
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>


^ permalink raw reply

* [PATCH v3 2/2] media: i2c: Add GC05A2 image sensor driver
From: Zhi Mao @ 2024-04-03  3:38 UTC (permalink / raw)
  To: mchehab, robh+dt, krzysztof.kozlowski+dt, sakari.ailus
  Cc: laurent.pinchart, shengnan.wang, yaya.chang,
	Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
	matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
	10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
	linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
	andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20240403033825.9072-1-zhi.mao@mediatek.com>

Add a V4L2 sub-device driver for Galaxycore GC05A2 image sensor.

Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 drivers/media/i2c/Kconfig  |   10 +
 drivers/media/i2c/Makefile |    1 +
 drivers/media/i2c/gc05a2.c | 1383 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1394 insertions(+)
 create mode 100644 drivers/media/i2c/gc05a2.c

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 56f276b920ab..97993bf160f9 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -70,6 +70,16 @@ config VIDEO_GC0308
 	  To compile this driver as a module, choose M here: the
 	  module will be called gc0308.
 
+config VIDEO_GC05A2
+	tristate "GalaxyCore gc05a2 sensor support"
+	select V4L2_CCI_I2C
+	help
+	  This is a Video4Linux2 sensor driver for the GalaxyCore gc05a2
+	  camera.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gc05a2.
+
 config VIDEO_GC2145
 	select V4L2_CCI_I2C
 	tristate "GalaxyCore GC2145 sensor support"
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..8ed6faf0f854 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_VIDEO_DW9768) += dw9768.o
 obj-$(CONFIG_VIDEO_DW9807_VCM) += dw9807-vcm.o
 obj-$(CONFIG_VIDEO_ET8EK8) += et8ek8/
 obj-$(CONFIG_VIDEO_GC0308) += gc0308.o
+obj-$(CONFIG_VIDEO_GC05A2) += gc05a2.o
 obj-$(CONFIG_VIDEO_GC2145) += gc2145.o
 obj-$(CONFIG_VIDEO_HI556) += hi556.o
 obj-$(CONFIG_VIDEO_HI846) += hi846.o
diff --git a/drivers/media/i2c/gc05a2.c b/drivers/media/i2c/gc05a2.c
new file mode 100644
index 000000000000..461d33055a3b
--- /dev/null
+++ b/drivers/media/i2c/gc05a2.c
@@ -0,0 +1,1383 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for GalaxyCore gc05a2 image sensor
+ *
+ * Copyright 2024 MediaTek
+ *
+ * Zhi Mao <zhi.mao@mediatek.com>
+ */
+#include <linux/array_size.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/math64.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/regulator/consumer.h>
+#include <linux/types.h>
+#include <linux/units.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define GC05A2_REG_TEST_PATTERN_EN CCI_REG8(0x008c)
+#define GC05A2_REG_TEST_PATTERN_IDX CCI_REG8(0x008d)
+#define GC05A2_TEST_PATTERN_EN 0x01
+
+#define GC05A2_STREAMING_REG CCI_REG8(0x0100)
+
+#define GC05A2_FLIP_REG CCI_REG8(0x0101)
+#define GC05A2_FLIP_H_MASK BIT(0)
+#define GC05A2_FLIP_V_MASK BIT(1)
+
+#define GC05A2_EXP_REG CCI_REG16(0x0202)
+#define GC05A2_EXP_MARGIN 16
+#define GC05A2_EXP_MIN 4
+#define GC05A2_EXP_STEP 1
+
+#define GC05A2_AGAIN_REG CCI_REG16(0x0204)
+#define GC05A2_AGAIN_MIN 1024
+#define GC05A2_AGAIN_MAX (1024 * 16)
+#define GC05A2_AGAIN_STEP 1
+
+#define GC05A2_FRAME_LENGTH_REG CCI_REG16(0x0340)
+#define GC05A2_VTS_MAX 0xffff
+
+#define GC05A2_REG_CHIP_ID CCI_REG16(0x03f0)
+#define GC05A2_CHIP_ID 0x05a2
+
+#define GC05A2_NATIVE_WIDTH 2592
+#define GC05A2_NATIVE_HEIGHT 1944
+
+#define GC05A2_DEFAULT_CLK_FREQ (24 * HZ_PER_MHZ)
+#define GC05A2_MBUS_CODE MEDIA_BUS_FMT_SGRBG10_1X10
+#define GC05A2_DATA_LANES 2
+#define GC05A2_RGB_DEPTH 10
+#define GC05A2_SLEEP_US  (2 * USEC_PER_MSEC)
+
+static const char *const gc05a2_test_pattern_menu[] = {
+	"No Pattern",  "Fade_to_gray_Color Bar", "Color Bar",
+	"PN9",	       "Horizental_gradient",    "Checkboard Pattern",
+	"Slant",       "Resolution",	         "Solid Black",
+	"Solid White",
+};
+
+static const s64 gc05a2_link_freq_menu_items[] = {
+	(448 * HZ_PER_MHZ),
+	(224 * HZ_PER_MHZ),
+};
+
+static const char *const gc05a2_supply_name[] = {
+	"avdd",
+	"dvdd",
+	"dovdd",
+};
+
+struct gc05a2 {
+	struct device *dev;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+
+	struct clk *xclk;
+	struct regulator_bulk_data supplies[ARRAY_SIZE(gc05a2_supply_name)];
+	struct gpio_desc *reset_gpio;
+
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *pixel_rate;
+	struct v4l2_ctrl *link_freq;
+	struct v4l2_ctrl *exposure;
+	struct v4l2_ctrl *vblank;
+	struct v4l2_ctrl *hblank;
+	struct v4l2_ctrl *hflip;
+	struct v4l2_ctrl *vflip;
+
+	struct regmap *regmap;
+	unsigned long link_freq_bitmap;
+
+	/* True if the device has been identified */
+	bool identified;
+	const struct gc05a2_mode *cur_mode;
+};
+
+struct gc05a2_reg_list {
+	u32 num_of_regs;
+	const struct cci_reg_sequence *regs;
+};
+
+static const struct cci_reg_sequence mode_2592x1944[] = {
+	/* system */
+	{ CCI_REG8(0x0135), 0x01 },
+
+	/* pre_setting */
+	{ CCI_REG8(0x0084), 0x21 },
+	{ CCI_REG8(0x0d05), 0xcc },
+	{ CCI_REG8(0x0218), 0x00 },
+	{ CCI_REG8(0x005e), 0x48 },
+	{ CCI_REG8(0x0d06), 0x01 },
+	{ CCI_REG8(0x0007), 0x16 },
+	{ CCI_REG8(0x0101), 0x00 },
+
+	/* analog */
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x28 },
+	{ CCI_REG8(0x0220), 0x07 },
+	{ CCI_REG8(0x0221), 0xd0 },
+	{ CCI_REG8(0x0202), 0x07 },
+	{ CCI_REG8(0x0203), 0x32 },
+	{ CCI_REG8(0x0340), 0x07 },
+	{ CCI_REG8(0x0341), 0xf0 },
+	{ CCI_REG8(0x0219), 0x00 },
+	{ CCI_REG8(0x0346), 0x00 },
+	{ CCI_REG8(0x0347), 0x04 },
+	{ CCI_REG8(0x0d14), 0x00 },
+	{ CCI_REG8(0x0d13), 0x05 },
+	{ CCI_REG8(0x0d16), 0x05 },
+	{ CCI_REG8(0x0d15), 0x1d },
+	{ CCI_REG8(0x00c0), 0x0a },
+	{ CCI_REG8(0x00c1), 0x30 },
+	{ CCI_REG8(0x034a), 0x07 },
+	{ CCI_REG8(0x034b), 0xa8 },
+	{ CCI_REG8(0x0e0a), 0x00 },
+	{ CCI_REG8(0x0e0b), 0x00 },
+	{ CCI_REG8(0x0e0e), 0x03 },
+	{ CCI_REG8(0x0e0f), 0x00 },
+	{ CCI_REG8(0x0e06), 0x0a },
+	{ CCI_REG8(0x0e23), 0x15 },
+	{ CCI_REG8(0x0e24), 0x15 },
+	{ CCI_REG8(0x0e2a), 0x10 },
+	{ CCI_REG8(0x0e2b), 0x10 },
+	{ CCI_REG8(0x0e17), 0x49 },
+	{ CCI_REG8(0x0e1b), 0x1c },
+	{ CCI_REG8(0x0e3a), 0x36 },
+	{ CCI_REG8(0x0d11), 0x84 },
+	{ CCI_REG8(0x0e52), 0x14 },
+	{ CCI_REG8(0x000b), 0x10 },
+	{ CCI_REG8(0x0008), 0x08 },
+	{ CCI_REG8(0x0223), 0x17 },
+	{ CCI_REG8(0x0d27), 0x39 },
+	{ CCI_REG8(0x0d22), 0x00 },
+	{ CCI_REG8(0x03f6), 0x0d },
+	{ CCI_REG8(0x0d04), 0x07 },
+	{ CCI_REG8(0x03f3), 0x72 },
+	{ CCI_REG8(0x03f4), 0xb8 },
+	{ CCI_REG8(0x03f5), 0xbc },
+	{ CCI_REG8(0x0d02), 0x73 },
+
+	/* auto load start */
+	{ CCI_REG8(0x00cb), 0x00 },
+
+	/* OUT 2592*1944 */
+	{ CCI_REG8(0x0350), 0x01 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x08 },
+	{ CCI_REG8(0x034c), 0x0a },
+	{ CCI_REG8(0x034d), 0x20 },
+	{ CCI_REG8(0x021f), 0x14 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0107), 0x05 },
+	{ CCI_REG8(0x0117), 0x01 },
+	{ CCI_REG8(0x0d81), 0x00 },
+	{ CCI_REG8(0x0d84), 0x0c },
+	{ CCI_REG8(0x0d85), 0xa8 },
+	{ CCI_REG8(0x0d86), 0x06 },
+	{ CCI_REG8(0x0d87), 0x55 },
+	{ CCI_REG8(0x0db3), 0x06 },
+	{ CCI_REG8(0x0db4), 0x08 },
+	{ CCI_REG8(0x0db5), 0x1e },
+	{ CCI_REG8(0x0db6), 0x02 },
+	{ CCI_REG8(0x0db8), 0x12 },
+	{ CCI_REG8(0x0db9), 0x0a },
+	{ CCI_REG8(0x0d93), 0x06 },
+	{ CCI_REG8(0x0d94), 0x09 },
+	{ CCI_REG8(0x0d95), 0x0d },
+	{ CCI_REG8(0x0d99), 0x0b },
+	{ CCI_REG8(0x0084), 0x01 },
+
+	/* OUT */
+	{ CCI_REG8(0x0110), 0x01 },
+};
+
+static const struct cci_reg_sequence mode_1280x720[] = {
+	/* system */
+	{ CCI_REG8(0x0135), 0x05 },
+
+	/*pre_setting*/
+	{ CCI_REG8(0x0084), 0x21 },
+	{ CCI_REG8(0x0d05), 0xcc },
+	{ CCI_REG8(0x0218), 0x80 },
+	{ CCI_REG8(0x005e), 0x49 },
+	{ CCI_REG8(0x0d06), 0x81 },
+	{ CCI_REG8(0x0007), 0x16 },
+	{ CCI_REG8(0x0101), 0x00 },
+
+	/* analog */
+	{ CCI_REG8(0x0342), 0x07 },
+	{ CCI_REG8(0x0343), 0x10 },
+	{ CCI_REG8(0x0220), 0x07 },
+	{ CCI_REG8(0x0221), 0xd0 },
+	{ CCI_REG8(0x0202), 0x03 },
+	{ CCI_REG8(0x0203), 0x32 },
+	{ CCI_REG8(0x0340), 0x04 },
+	{ CCI_REG8(0x0341), 0x08 },
+	{ CCI_REG8(0x0219), 0x00 },
+	{ CCI_REG8(0x0346), 0x01 },
+	{ CCI_REG8(0x0347), 0x00 },
+	{ CCI_REG8(0x0d14), 0x00 },
+	{ CCI_REG8(0x0d13), 0x05 },
+	{ CCI_REG8(0x0d16), 0x05 },
+	{ CCI_REG8(0x0d15), 0x1d },
+	{ CCI_REG8(0x00c0), 0x0a },
+	{ CCI_REG8(0x00c1), 0x30 },
+	{ CCI_REG8(0x034a), 0x05 },
+	{ CCI_REG8(0x034b), 0xb0 },
+	{ CCI_REG8(0x0e0a), 0x00 },
+	{ CCI_REG8(0x0e0b), 0x00 },
+	{ CCI_REG8(0x0e0e), 0x03 },
+	{ CCI_REG8(0x0e0f), 0x00 },
+	{ CCI_REG8(0x0e06), 0x0a },
+	{ CCI_REG8(0x0e23), 0x15 },
+	{ CCI_REG8(0x0e24), 0x15 },
+	{ CCI_REG8(0x0e2a), 0x10 },
+	{ CCI_REG8(0x0e2b), 0x10 },
+	{ CCI_REG8(0x0e17), 0x49 },
+	{ CCI_REG8(0x0e1b), 0x1c },
+	{ CCI_REG8(0x0e3a), 0x36 },
+	{ CCI_REG8(0x0d11), 0x84 },
+	{ CCI_REG8(0x0e52), 0x14 },
+	{ CCI_REG8(0x000b), 0x0e },
+	{ CCI_REG8(0x0008), 0x03 },
+	{ CCI_REG8(0x0223), 0x16 },
+	{ CCI_REG8(0x0d27), 0x39 },
+	{ CCI_REG8(0x0d22), 0x00 },
+	{ CCI_REG8(0x03f6), 0x0d },
+	{ CCI_REG8(0x0d04), 0x07 },
+	{ CCI_REG8(0x03f3), 0x72 },
+	{ CCI_REG8(0x03f4), 0xb8 },
+	{ CCI_REG8(0x03f5), 0xbc },
+	{ CCI_REG8(0x0d02), 0x73 },
+
+	/* auto load start */
+	{ CCI_REG8(0x00cb), 0xfc },
+
+	/* OUT 1280x720 */
+	{ CCI_REG8(0x0350), 0x01 },
+	{ CCI_REG8(0x0353), 0x00 },
+	{ CCI_REG8(0x0354), 0x0c },
+	{ CCI_REG8(0x034c), 0x05 },
+	{ CCI_REG8(0x034d), 0x00 },
+	{ CCI_REG8(0x021f), 0x14 },
+
+	/* MIPI */
+	{ CCI_REG8(0x0107), 0x05 },
+	{ CCI_REG8(0x0117), 0x01 },
+	{ CCI_REG8(0x0d81), 0x00 },
+	{ CCI_REG8(0x0d84), 0x06 },
+	{ CCI_REG8(0x0d85), 0x40 },
+	{ CCI_REG8(0x0d86), 0x03 },
+	{ CCI_REG8(0x0d87), 0x21 },
+	{ CCI_REG8(0x0db3), 0x03 },
+	{ CCI_REG8(0x0db4), 0x04 },
+	{ CCI_REG8(0x0db5), 0x0d },
+	{ CCI_REG8(0x0db6), 0x01 },
+	{ CCI_REG8(0x0db8), 0x04 },
+	{ CCI_REG8(0x0db9), 0x06 },
+	{ CCI_REG8(0x0d93), 0x03 },
+	{ CCI_REG8(0x0d94), 0x04 },
+	{ CCI_REG8(0x0d95), 0x05 },
+	{ CCI_REG8(0x0d99), 0x06 },
+	{ CCI_REG8(0x0084), 0x01 },
+
+	/* OUT */
+	{ CCI_REG8(0x0110), 0x01 },
+};
+
+static const struct cci_reg_sequence mode_table_common[] = {
+	{ GC05A2_STREAMING_REG, 0x00 },
+	/* system */
+	{ CCI_REG8(0x0315), 0xd4 },
+	{ CCI_REG8(0x0d06), 0x01 },
+	{ CCI_REG8(0x0a70), 0x80 },
+	{ CCI_REG8(0x031a), 0x00 },
+	{ CCI_REG8(0x0314), 0x00 },
+	{ CCI_REG8(0x0130), 0x08 },
+	{ CCI_REG8(0x0132), 0x01 },
+	{ CCI_REG8(0x0136), 0x38 },
+	{ CCI_REG8(0x0137), 0x03 },
+	{ CCI_REG8(0x0134), 0x5b },
+	{ CCI_REG8(0x031c), 0xe0 },
+	{ CCI_REG8(0x0d82), 0x14 },
+	{ CCI_REG8(0x0dd1), 0x56 },
+
+	/* gate_mode */
+	{ CCI_REG8(0x0af4), 0x01 },
+	{ CCI_REG8(0x0002), 0x10 },
+	{ CCI_REG8(0x00c3), 0x34 },
+
+	/* auto load start */
+	{ CCI_REG8(0x00c4), 0x00 },
+	{ CCI_REG8(0x00c5), 0x01 },
+	{ CCI_REG8(0x0af6), 0x00 },
+	{ CCI_REG8(0x0ba0), 0x17 },
+	{ CCI_REG8(0x0ba1), 0x00 },
+	{ CCI_REG8(0x0ba2), 0x00 },
+	{ CCI_REG8(0x0ba3), 0x00 },
+	{ CCI_REG8(0x0ba4), 0x03 },
+	{ CCI_REG8(0x0ba5), 0x00 },
+	{ CCI_REG8(0x0ba6), 0x00 },
+	{ CCI_REG8(0x0ba7), 0x00 },
+	{ CCI_REG8(0x0ba8), 0x40 },
+	{ CCI_REG8(0x0ba9), 0x00 },
+	{ CCI_REG8(0x0baa), 0x00 },
+	{ CCI_REG8(0x0bab), 0x00 },
+	{ CCI_REG8(0x0bac), 0x40 },
+	{ CCI_REG8(0x0bad), 0x00 },
+	{ CCI_REG8(0x0bae), 0x00 },
+	{ CCI_REG8(0x0baf), 0x00 },
+	{ CCI_REG8(0x0bb0), 0x02 },
+	{ CCI_REG8(0x0bb1), 0x00 },
+	{ CCI_REG8(0x0bb2), 0x00 },
+	{ CCI_REG8(0x0bb3), 0x00 },
+	{ CCI_REG8(0x0bb8), 0x02 },
+	{ CCI_REG8(0x0bb9), 0x00 },
+	{ CCI_REG8(0x0bba), 0x00 },
+	{ CCI_REG8(0x0bbb), 0x00 },
+	{ CCI_REG8(0x0a70), 0x80 },
+	{ CCI_REG8(0x0a71), 0x00 },
+	{ CCI_REG8(0x0a72), 0x00 },
+	{ CCI_REG8(0x0a66), 0x00 },
+	{ CCI_REG8(0x0a67), 0x80 },
+	{ CCI_REG8(0x0a4d), 0x4e },
+	{ CCI_REG8(0x0a50), 0x00 },
+	{ CCI_REG8(0x0a4f), 0x0c },
+	{ CCI_REG8(0x0a66), 0x00 },
+	{ CCI_REG8(0x00ca), 0x00 },
+	{ CCI_REG8(0x00cc), 0x00 },
+	{ CCI_REG8(0x00cd), 0x00 },
+	{ CCI_REG8(0x0aa1), 0x00 },
+	{ CCI_REG8(0x0aa2), 0xe0 },
+	{ CCI_REG8(0x0aa3), 0x00 },
+	{ CCI_REG8(0x0aa4), 0x40 },
+	{ CCI_REG8(0x0a90), 0x03 },
+	{ CCI_REG8(0x0a91), 0x0e },
+	{ CCI_REG8(0x0a94), 0x80 },
+
+	/* standby */
+	{ CCI_REG8(0x0af6), 0x20 },
+	{ CCI_REG8(0x0b00), 0x91 },
+	{ CCI_REG8(0x0b01), 0x17 },
+	{ CCI_REG8(0x0b02), 0x01 },
+	{ CCI_REG8(0x0b03), 0x00 },
+	{ CCI_REG8(0x0b04), 0x01 },
+	{ CCI_REG8(0x0b05), 0x17 },
+	{ CCI_REG8(0x0b06), 0x01 },
+	{ CCI_REG8(0x0b07), 0x00 },
+	{ CCI_REG8(0x0ae9), 0x01 },
+	{ CCI_REG8(0x0aea), 0x02 },
+	{ CCI_REG8(0x0ae8), 0x53 },
+	{ CCI_REG8(0x0ae8), 0x43 },
+
+	/* gain_partition */
+	{ CCI_REG8(0x0af6), 0x30 },
+	{ CCI_REG8(0x0b00), 0x08 },
+	{ CCI_REG8(0x0b01), 0x0f },
+	{ CCI_REG8(0x0b02), 0x00 },
+	{ CCI_REG8(0x0b04), 0x1c },
+	{ CCI_REG8(0x0b05), 0x24 },
+	{ CCI_REG8(0x0b06), 0x00 },
+	{ CCI_REG8(0x0b08), 0x30 },
+	{ CCI_REG8(0x0b09), 0x40 },
+	{ CCI_REG8(0x0b0a), 0x00 },
+	{ CCI_REG8(0x0b0c), 0x0e },
+	{ CCI_REG8(0x0b0d), 0x2a },
+	{ CCI_REG8(0x0b0e), 0x00 },
+	{ CCI_REG8(0x0b10), 0x0e },
+	{ CCI_REG8(0x0b11), 0x2b },
+	{ CCI_REG8(0x0b12), 0x00 },
+	{ CCI_REG8(0x0b14), 0x0e },
+	{ CCI_REG8(0x0b15), 0x23 },
+	{ CCI_REG8(0x0b16), 0x00 },
+	{ CCI_REG8(0x0b18), 0x0e },
+	{ CCI_REG8(0x0b19), 0x24 },
+	{ CCI_REG8(0x0b1a), 0x00 },
+	{ CCI_REG8(0x0b1c), 0x0c },
+	{ CCI_REG8(0x0b1d), 0x0c },
+	{ CCI_REG8(0x0b1e), 0x00 },
+	{ CCI_REG8(0x0b20), 0x03 },
+	{ CCI_REG8(0x0b21), 0x03 },
+	{ CCI_REG8(0x0b22), 0x00 },
+	{ CCI_REG8(0x0b24), 0x0e },
+	{ CCI_REG8(0x0b25), 0x0e },
+	{ CCI_REG8(0x0b26), 0x00 },
+	{ CCI_REG8(0x0b28), 0x03 },
+	{ CCI_REG8(0x0b29), 0x03 },
+	{ CCI_REG8(0x0b2a), 0x00 },
+	{ CCI_REG8(0x0b2c), 0x12 },
+	{ CCI_REG8(0x0b2d), 0x12 },
+	{ CCI_REG8(0x0b2e), 0x00 },
+	{ CCI_REG8(0x0b30), 0x08 },
+	{ CCI_REG8(0x0b31), 0x08 },
+	{ CCI_REG8(0x0b32), 0x00 },
+	{ CCI_REG8(0x0b34), 0x14 },
+	{ CCI_REG8(0x0b35), 0x14 },
+	{ CCI_REG8(0x0b36), 0x00 },
+	{ CCI_REG8(0x0b38), 0x10 },
+	{ CCI_REG8(0x0b39), 0x10 },
+	{ CCI_REG8(0x0b3a), 0x00 },
+	{ CCI_REG8(0x0b3c), 0x16 },
+	{ CCI_REG8(0x0b3d), 0x16 },
+	{ CCI_REG8(0x0b3e), 0x00 },
+	{ CCI_REG8(0x0b40), 0x10 },
+	{ CCI_REG8(0x0b41), 0x10 },
+	{ CCI_REG8(0x0b42), 0x00 },
+	{ CCI_REG8(0x0b44), 0x19 },
+	{ CCI_REG8(0x0b45), 0x19 },
+	{ CCI_REG8(0x0b46), 0x00 },
+	{ CCI_REG8(0x0b48), 0x16 },
+	{ CCI_REG8(0x0b49), 0x16 },
+	{ CCI_REG8(0x0b4a), 0x00 },
+	{ CCI_REG8(0x0b4c), 0x19 },
+	{ CCI_REG8(0x0b4d), 0x19 },
+	{ CCI_REG8(0x0b4e), 0x00 },
+	{ CCI_REG8(0x0b50), 0x16 },
+	{ CCI_REG8(0x0b51), 0x16 },
+	{ CCI_REG8(0x0b52), 0x00 },
+	{ CCI_REG8(0x0b80), 0x01 },
+	{ CCI_REG8(0x0b81), 0x00 },
+	{ CCI_REG8(0x0b82), 0x00 },
+	{ CCI_REG8(0x0b84), 0x00 },
+	{ CCI_REG8(0x0b85), 0x00 },
+	{ CCI_REG8(0x0b86), 0x00 },
+	{ CCI_REG8(0x0b88), 0x01 },
+	{ CCI_REG8(0x0b89), 0x6a },
+	{ CCI_REG8(0x0b8a), 0x00 },
+	{ CCI_REG8(0x0b8c), 0x00 },
+	{ CCI_REG8(0x0b8d), 0x01 },
+	{ CCI_REG8(0x0b8e), 0x00 },
+	{ CCI_REG8(0x0b90), 0x01 },
+	{ CCI_REG8(0x0b91), 0xf6 },
+	{ CCI_REG8(0x0b92), 0x00 },
+	{ CCI_REG8(0x0b94), 0x00 },
+	{ CCI_REG8(0x0b95), 0x02 },
+	{ CCI_REG8(0x0b96), 0x00 },
+	{ CCI_REG8(0x0b98), 0x02 },
+	{ CCI_REG8(0x0b99), 0xc4 },
+	{ CCI_REG8(0x0b9a), 0x00 },
+	{ CCI_REG8(0x0b9c), 0x00 },
+	{ CCI_REG8(0x0b9d), 0x03 },
+	{ CCI_REG8(0x0b9e), 0x00 },
+	{ CCI_REG8(0x0ba0), 0x03 },
+	{ CCI_REG8(0x0ba1), 0xd8 },
+	{ CCI_REG8(0x0ba2), 0x00 },
+	{ CCI_REG8(0x0ba4), 0x00 },
+	{ CCI_REG8(0x0ba5), 0x04 },
+	{ CCI_REG8(0x0ba6), 0x00 },
+	{ CCI_REG8(0x0ba8), 0x05 },
+	{ CCI_REG8(0x0ba9), 0x4d },
+	{ CCI_REG8(0x0baa), 0x00 },
+	{ CCI_REG8(0x0bac), 0x00 },
+	{ CCI_REG8(0x0bad), 0x05 },
+	{ CCI_REG8(0x0bae), 0x00 },
+	{ CCI_REG8(0x0bb0), 0x07 },
+	{ CCI_REG8(0x0bb1), 0x3e },
+	{ CCI_REG8(0x0bb2), 0x00 },
+	{ CCI_REG8(0x0bb4), 0x00 },
+	{ CCI_REG8(0x0bb5), 0x06 },
+	{ CCI_REG8(0x0bb6), 0x00 },
+	{ CCI_REG8(0x0bb8), 0x0a },
+	{ CCI_REG8(0x0bb9), 0x1a },
+	{ CCI_REG8(0x0bba), 0x00 },
+	{ CCI_REG8(0x0bbc), 0x09 },
+	{ CCI_REG8(0x0bbd), 0x36 },
+	{ CCI_REG8(0x0bbe), 0x00 },
+	{ CCI_REG8(0x0bc0), 0x0e },
+	{ CCI_REG8(0x0bc1), 0x66 },
+	{ CCI_REG8(0x0bc2), 0x00 },
+	{ CCI_REG8(0x0bc4), 0x10 },
+	{ CCI_REG8(0x0bc5), 0x06 },
+	{ CCI_REG8(0x0bc6), 0x00 },
+	{ CCI_REG8(0x02c1), 0xe0 },
+	{ CCI_REG8(0x0207), 0x04 },
+	{ CCI_REG8(0x02c2), 0x10 },
+	{ CCI_REG8(0x02c3), 0x74 },
+	{ CCI_REG8(0x02c5), 0x09 },
+	{ CCI_REG8(0x02c1), 0xe0 },
+	{ CCI_REG8(0x0207), 0x04 },
+	{ CCI_REG8(0x02c2), 0x10 },
+	{ CCI_REG8(0x02c5), 0x09 },
+	{ CCI_REG8(0x02c1), 0xe0 },
+	{ CCI_REG8(0x0207), 0x04 },
+	{ CCI_REG8(0x02c2), 0x10 },
+	{ CCI_REG8(0x02c5), 0x09 },
+
+	/* auto load CH_GAIN */
+	{ CCI_REG8(0x0aa1), 0x15 },
+	{ CCI_REG8(0x0aa2), 0x50 },
+	{ CCI_REG8(0x0aa3), 0x00 },
+	{ CCI_REG8(0x0aa4), 0x09 },
+	{ CCI_REG8(0x0a90), 0x25 },
+	{ CCI_REG8(0x0a91), 0x0e },
+	{ CCI_REG8(0x0a94), 0x80 },
+
+	/* ISP */
+	{ CCI_REG8(0x0050), 0x00 },
+	{ CCI_REG8(0x0089), 0x83 },
+	{ CCI_REG8(0x005a), 0x40 },
+	{ CCI_REG8(0x00c3), 0x35 },
+	{ CCI_REG8(0x00c4), 0x80 },
+	{ CCI_REG8(0x0080), 0x10 },
+	{ CCI_REG8(0x0040), 0x12 },
+	{ CCI_REG8(0x0053), 0x0a },
+	{ CCI_REG8(0x0054), 0x44 },
+	{ CCI_REG8(0x0055), 0x32 },
+	{ CCI_REG8(0x0058), 0x89 },
+	{ CCI_REG8(0x004a), 0x03 },
+	{ CCI_REG8(0x0048), 0xf0 },
+	{ CCI_REG8(0x0049), 0x0f },
+	{ CCI_REG8(0x0041), 0x20 },
+	{ CCI_REG8(0x0043), 0x0a },
+	{ CCI_REG8(0x009d), 0x08 },
+	{ CCI_REG8(0x0236), 0x40 },
+
+	/* gain */
+	{ CCI_REG8(0x0204), 0x04 },
+	{ CCI_REG8(0x0205), 0x00 },
+	{ CCI_REG8(0x02b3), 0x00 },
+	{ CCI_REG8(0x02b4), 0x00 },
+	{ CCI_REG8(0x009e), 0x01 },
+	{ CCI_REG8(0x009f), 0x94 },
+
+	/* auto load REG */
+	{ CCI_REG8(0x0aa1), 0x10 },
+	{ CCI_REG8(0x0aa2), 0xf8 },
+	{ CCI_REG8(0x0aa3), 0x00 },
+	{ CCI_REG8(0x0aa4), 0x1f },
+	{ CCI_REG8(0x0a90), 0x11 },
+	{ CCI_REG8(0x0a91), 0x0e },
+	{ CCI_REG8(0x0a94), 0x80 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x0a90), 0x00 },
+	{ CCI_REG8(0x0a70), 0x00 },
+	{ CCI_REG8(0x0a67), 0x00 },
+	{ CCI_REG8(0x0af4), 0x29 },
+
+	/* DPHY */
+	{ CCI_REG8(0x0d80), 0x07 },
+	{ CCI_REG8(0x0dd3), 0x18 },
+
+	/* CISCTL_Reset */
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x30 },
+	{ CCI_REG8(0x0d17), 0x06 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x0d17), 0x00 },
+	{ CCI_REG8(0x031c), 0x93 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x031c), 0x80 },
+	{ CCI_REG8(0x03fe), 0x30 },
+	{ CCI_REG8(0x0d17), 0x06 },
+	{ CCI_REG8(0x03fe), 0x00 },
+	{ CCI_REG8(0x0d17), 0x00 },
+	{ CCI_REG8(0x031c), 0x93 },
+};
+
+struct gc05a2_mode {
+	u32 width;
+	u32 height;
+	const struct gc05a2_reg_list reg_list;
+
+	u32 hts; /* Horizontal timining size */
+	u32 vts_def; /* Default vertical timining size */
+	u32 vts_min; /* Min vertical timining size */
+};
+
+/* Declare modes in order, from biggest to smallest height. */
+static const struct gc05a2_mode gc05a2_modes[] = {
+	{
+		/* 2592*1944@30fps */
+		.width = GC05A2_NATIVE_WIDTH,
+		.height = GC05A2_NATIVE_HEIGHT,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_2592x1944),
+			.regs = mode_2592x1944,
+		},
+		.hts = 3664,
+		.vts_def = 2032,
+		.vts_min = 2032,
+	},
+	{
+		/* 1280*720@60fps */
+		.width = 1280,
+		.height = 720,
+		.reg_list = {
+			.num_of_regs = ARRAY_SIZE(mode_1280x720),
+			.regs = mode_1280x720,
+		},
+		.hts = 3616,
+		.vts_def = 1032,
+		.vts_min = 1032,
+	},
+};
+
+static inline struct gc05a2 *to_gc05a2(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct gc05a2, sd);
+}
+
+static int gc05a2_power_on(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(gc05a2_supply_name),
+				    gc05a2->supplies);
+	if (ret < 0) {
+		dev_err(gc05a2->dev, "failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(gc05a2->xclk);
+	if (ret < 0) {
+		regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
+				       gc05a2->supplies);
+		dev_err(gc05a2->dev, "clk prepare enable failed\n");
+		return ret;
+	}
+
+	fsleep(GC05A2_SLEEP_US);
+
+	gpiod_set_value_cansleep(gc05a2->reset_gpio, 0);
+	fsleep(GC05A2_SLEEP_US);
+
+	return 0;
+}
+
+static int gc05a2_power_off(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+
+	clk_disable_unprepare(gc05a2->xclk);
+	gpiod_set_value_cansleep(gc05a2->reset_gpio, 1);
+	regulator_bulk_disable(ARRAY_SIZE(gc05a2_supply_name),
+			       gc05a2->supplies);
+
+	return 0;
+}
+
+static int gc05a2_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = GC05A2_MBUS_CODE;
+
+	return 0;
+}
+
+static int gc05a2_enum_frame_size(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->code != GC05A2_MBUS_CODE)
+		return -EINVAL;
+
+	if (fse->index >= ARRAY_SIZE(gc05a2_modes))
+		return -EINVAL;
+
+	fse->min_width = gc05a2_modes[fse->index].width;
+	fse->max_width = gc05a2_modes[fse->index].width;
+	fse->min_height = gc05a2_modes[fse->index].height;
+	fse->max_height = gc05a2_modes[fse->index].height;
+
+	return 0;
+}
+
+static int gc05a2_update_cur_mode_controls(struct gc05a2 *gc05a2,
+					   const struct gc05a2_mode *mode)
+{
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ret = __v4l2_ctrl_modify_range(gc05a2->vblank,
+				       mode->vts_min - mode->height,
+				       GC05A2_VTS_MAX - mode->height, 1,
+				       mode->vts_def - mode->height);
+	if (ret) {
+		dev_err(gc05a2->dev, "VB ctrl range update failed\n");
+		return ret;
+	}
+
+	h_blank = mode->hts - mode->width;
+	ret = __v4l2_ctrl_modify_range(gc05a2->hblank, h_blank, h_blank, 1,
+				       h_blank);
+	if (ret) {
+		dev_err(gc05a2->dev, "HB ctrl range update failed\n");
+		return ret;
+	}
+
+	exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
+	ret = __v4l2_ctrl_modify_range(gc05a2->exposure, GC05A2_EXP_MIN,
+				       exposure_max, GC05A2_EXP_STEP,
+				       exposure_max);
+	if (ret) {
+		dev_err(gc05a2->dev, "exposure ctrl range update failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void gc05a2_update_pad_format(struct gc05a2 *gc08a3,
+				     const struct gc05a2_mode *mode,
+				     struct v4l2_mbus_framefmt *fmt)
+{
+	fmt->width = mode->width;
+	fmt->height = mode->height;
+	fmt->code = GC05A2_MBUS_CODE;
+	fmt->field = V4L2_FIELD_NONE;
+	fmt->colorspace = V4L2_COLORSPACE_RAW;
+	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
+	fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
+	fmt->xfer_func = V4L2_XFER_FUNC_NONE;
+}
+
+static int gc05a2_set_format(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+	struct v4l2_mbus_framefmt *mbus_fmt;
+	struct v4l2_rect *crop;
+	const struct gc05a2_mode *mode;
+
+	mode = v4l2_find_nearest_size(gc05a2_modes, ARRAY_SIZE(gc05a2_modes),
+				      width, height, fmt->format.width,
+				      fmt->format.height);
+
+	/* update crop info to subdev state */
+	crop = v4l2_subdev_state_get_crop(state, 0);
+	crop->width = mode->width;
+	crop->height = mode->height;
+
+	/* update fmt info to subdev state */
+	gc05a2_update_pad_format(gc05a2, mode, &fmt->format);
+	mbus_fmt = v4l2_subdev_state_get_format(state, 0);
+	*mbus_fmt = fmt->format;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+		return 0;
+	gc05a2->cur_mode = mode;
+	gc05a2_update_cur_mode_controls(gc05a2, mode);
+
+	return 0;
+}
+
+static int gc05a2_get_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_state *state,
+				struct v4l2_subdev_selection *sel)
+{
+	switch (sel->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP:
+		sel->r = *v4l2_subdev_state_get_crop(state, 0);
+		break;
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		sel->r.top = 0;
+		sel->r.left = 0;
+		sel->r.width = GC05A2_NATIVE_WIDTH;
+		sel->r.height = GC05A2_NATIVE_HEIGHT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int gc05a2_init_state(struct v4l2_subdev *sd,
+			     struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_TRY,
+		.pad = 0,
+		.format = {
+			.code = GC05A2_MBUS_CODE,
+			.width = gc05a2_modes[0].width,
+			.height = gc05a2_modes[0].height,
+		},
+	};
+
+	gc05a2_set_format(sd, state, &fmt);
+
+	return 0;
+}
+
+static int gc05a2_set_ctrl_hflip(struct gc05a2 *gc05a2, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc05a2->dev, "read hflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
+			       GC05A2_FLIP_H_MASK,
+			       ctrl_val ? GC05A2_FLIP_H_MASK : 0, NULL);
+}
+
+static int gc05a2_set_ctrl_vflip(struct gc05a2 *gc05a2, u32 ctrl_val)
+{
+	int ret;
+	u64 val;
+
+	ret = cci_read(gc05a2->regmap, GC05A2_FLIP_REG, &val, NULL);
+	if (ret) {
+		dev_err(gc05a2->dev, "read vflip register failed: %d\n", ret);
+		return ret;
+	}
+
+	return cci_update_bits(gc05a2->regmap, GC05A2_FLIP_REG,
+			       GC05A2_FLIP_V_MASK,
+			       ctrl_val ? GC05A2_FLIP_V_MASK : 0, NULL);
+}
+
+static int gc05a2_test_pattern(struct gc05a2 *gc05a2, u32 pattern_menu)
+{
+	u32 pattern;
+	int ret;
+
+	if (pattern_menu) {
+		switch (pattern_menu) {
+		case 1:
+		case 2:
+		case 3:
+		case 4:
+		case 5:
+		case 6:
+		case 7:
+			pattern = pattern_menu << 4;
+			break;
+
+		case 8:
+			pattern = 0;
+			break;
+
+		case 9:
+			pattern = 4;
+			break;
+
+		default:
+			pattern = 0x00;
+			break;
+		}
+
+		ret = cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_IDX,
+				pattern, NULL);
+		if (ret)
+			return ret;
+
+		return cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_EN,
+				 GC05A2_TEST_PATTERN_EN, NULL);
+	} else {
+		return cci_write(gc05a2->regmap, GC05A2_REG_TEST_PATTERN_EN,
+				 0x00, NULL);
+	}
+}
+
+static int gc05a2_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct gc05a2 *gc05a2 =
+		container_of(ctrl->handler, struct gc05a2, ctrls);
+	int ret = 0;
+	s64 exposure_max;
+	struct v4l2_subdev_state *state;
+	const struct v4l2_mbus_framefmt *format;
+
+	state = v4l2_subdev_get_locked_active_state(&gc05a2->sd);
+	format = v4l2_subdev_state_get_format(state, 0);
+
+	if (ctrl->id == V4L2_CID_VBLANK) {
+		/* Update max exposure while meeting expected vblanking */
+		exposure_max = format->height + ctrl->val - GC05A2_EXP_MARGIN;
+		__v4l2_ctrl_modify_range(gc05a2->exposure,
+					 gc05a2->exposure->minimum,
+					 exposure_max, gc05a2->exposure->step,
+					 exposure_max);
+	}
+
+	/*
+	 * Applying V4L2 control value only happens
+	 * when power is on for streaming.
+	 */
+	if (!pm_runtime_get_if_active(gc05a2->dev))
+		return 0;
+
+	switch (ctrl->id) {
+	case V4L2_CID_EXPOSURE:
+		ret = cci_write(gc05a2->regmap, GC05A2_EXP_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_ANALOGUE_GAIN:
+		ret = cci_write(gc05a2->regmap, GC05A2_AGAIN_REG,
+				ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_VBLANK:
+		ret = cci_write(gc05a2->regmap, GC05A2_FRAME_LENGTH_REG,
+				gc05a2->cur_mode->height + ctrl->val, NULL);
+		break;
+
+	case V4L2_CID_HFLIP:
+		ret = gc05a2_set_ctrl_hflip(gc05a2, ctrl->val);
+		break;
+
+	case V4L2_CID_VFLIP:
+		ret = gc05a2_set_ctrl_vflip(gc05a2, ctrl->val);
+		break;
+
+	case V4L2_CID_TEST_PATTERN:
+		ret = gc05a2_test_pattern(gc05a2, ctrl->val);
+		break;
+
+	default:
+		break;
+	}
+
+	pm_runtime_put(gc05a2->dev);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops gc05a2_ctrl_ops = {
+	.s_ctrl = gc05a2_set_ctrl,
+};
+
+static int gc05a2_identify_module(struct gc05a2 *gc05a2)
+{
+	u64 val;
+	int ret;
+
+	if (gc05a2->identified)
+		return 0;
+
+	ret = cci_read(gc05a2->regmap, GC05A2_REG_CHIP_ID, &val, NULL);
+	if (ret)
+		return ret;
+
+	if (val != GC05A2_CHIP_ID) {
+		dev_err(gc05a2->dev, "chip id mismatch: 0x%x!=0x%llx",
+			GC05A2_CHIP_ID, val);
+		return -ENXIO;
+	}
+
+	gc05a2->identified = true;
+
+	return 0;
+}
+
+static int gc05a2_start_streaming(struct gc05a2 *gc05a2)
+{
+	const struct gc05a2_mode *mode;
+	const struct gc05a2_reg_list *reg_list;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(gc05a2->dev);
+	if (ret < 0)
+		return ret;
+
+	ret = gc05a2_identify_module(gc05a2);
+	if (ret)
+		goto err_rpm_put;
+
+	ret = cci_multi_reg_write(gc05a2->regmap,
+				  mode_table_common,
+				  ARRAY_SIZE(mode_table_common), NULL);
+	if (ret)
+		goto err_rpm_put;
+
+	mode = gc05a2->cur_mode;
+	reg_list = &mode->reg_list;
+
+	ret = cci_multi_reg_write(gc05a2->regmap,
+				  reg_list->regs, reg_list->num_of_regs, NULL);
+	if (ret < 0)
+		goto err_rpm_put;
+
+	ret = __v4l2_ctrl_handler_setup(&gc05a2->ctrls);
+	if (ret < 0) {
+		dev_err(gc05a2->dev, "could not sync v4l2 controls\n");
+		goto err_rpm_put;
+	}
+
+	ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 1, NULL);
+	if (ret < 0) {
+		dev_err(gc05a2->dev, "write STREAMING_REG failed: %d\n", ret);
+		goto err_rpm_put;
+	}
+
+	return 0;
+
+err_rpm_put:
+	pm_runtime_put(gc05a2->dev);
+	return ret;
+}
+
+static int gc05a2_stop_streaming(struct gc05a2 *gc05a2)
+{
+	int ret;
+
+	ret = cci_write(gc05a2->regmap, GC05A2_STREAMING_REG, 0, NULL);
+	if (ret < 0)
+		dev_err(gc05a2->dev, "could not sent stop streaming %d\n", ret);
+
+	pm_runtime_put(gc05a2->dev);
+	return ret;
+}
+
+static int gc05a2_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	struct gc05a2 *gc05a2 = to_gc05a2(subdev);
+	struct v4l2_subdev_state *state;
+	int ret;
+
+	state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+	if (enable)
+		ret = gc05a2_start_streaming(gc05a2);
+	else
+		ret = gc05a2_stop_streaming(gc05a2);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops gc05a2_video_ops = {
+	.s_stream = gc05a2_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops gc05a2_subdev_pad_ops = {
+	.enum_mbus_code = gc05a2_enum_mbus_code,
+	.enum_frame_size = gc05a2_enum_frame_size,
+	.get_fmt = v4l2_subdev_get_fmt,
+	.set_fmt = gc05a2_set_format,
+	.get_selection = gc05a2_get_selection,
+};
+
+static const struct v4l2_subdev_core_ops gc05a2_core_ops = {
+	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_ops gc05a2_subdev_ops = {
+	.core = &gc05a2_core_ops,
+	.video = &gc05a2_video_ops,
+	.pad = &gc05a2_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops gc05a2_internal_ops = {
+	.init_state = gc05a2_init_state,
+};
+
+static int gc05a2_get_regulators(struct device *dev, struct gc05a2 *gc05a2)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(gc05a2_supply_name); i++)
+		gc05a2->supplies[i].supply = gc05a2_supply_name[i];
+
+	return devm_regulator_bulk_get(dev, ARRAY_SIZE(gc05a2_supply_name),
+				       gc05a2->supplies);
+}
+
+static int gc05a2_parse_fwnode(struct gc05a2 *gc05a2)
+{
+	struct fwnode_handle *endpoint;
+	struct v4l2_fwnode_endpoint bus_cfg = {
+		.bus_type = V4L2_MBUS_CSI2_DPHY,
+	};
+	int ret;
+	struct device *dev = gc05a2->dev;
+
+	endpoint =
+		fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
+						FWNODE_GRAPH_ENDPOINT_NEXT);
+	if (!endpoint) {
+		dev_err(dev, "endpoint node not found\n");
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg);
+	if (ret) {
+		dev_err(dev, "parsing endpoint node failed\n");
+		goto done;
+	}
+
+	ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
+				       bus_cfg.nr_of_link_frequencies,
+				       gc05a2_link_freq_menu_items,
+				       ARRAY_SIZE(gc05a2_link_freq_menu_items),
+				       &gc05a2->link_freq_bitmap);
+	if (ret)
+		goto done;
+
+done:
+	v4l2_fwnode_endpoint_free(&bus_cfg);
+	fwnode_handle_put(endpoint);
+	return ret;
+}
+
+static u64 gc05a2_to_pixel_rate(u32 f_index)
+{
+	u64 pixel_rate =
+		gc05a2_link_freq_menu_items[f_index] * 2 * GC05A2_DATA_LANES;
+
+	return div_u64(pixel_rate, GC05A2_RGB_DEPTH);
+}
+
+static int gc05a2_init_controls(struct gc05a2 *gc05a2)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&gc05a2->sd);
+	const struct gc05a2_mode *mode = &gc05a2_modes[0];
+	const struct v4l2_ctrl_ops *ops = &gc05a2_ctrl_ops;
+	struct v4l2_fwnode_device_properties props;
+	struct v4l2_ctrl_handler *ctrl_hdlr;
+	s64 exposure_max, h_blank;
+	int ret;
+
+	ctrl_hdlr = &gc05a2->ctrls;
+	ret = v4l2_ctrl_handler_init(ctrl_hdlr, 9);
+	if (ret)
+		return ret;
+
+	gc05a2->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					  V4L2_CID_HFLIP, 0, 1, 1, 0);
+	gc05a2->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					  V4L2_CID_VFLIP, 0, 1, 1, 0);
+	v4l2_ctrl_cluster(2, &gc05a2->hflip);
+
+	gc05a2->link_freq =
+	v4l2_ctrl_new_int_menu(ctrl_hdlr,
+			       &gc05a2_ctrl_ops,
+			       V4L2_CID_LINK_FREQ,
+			       ARRAY_SIZE(gc05a2_link_freq_menu_items) - 1,
+			       0,
+			       gc05a2_link_freq_menu_items);
+	if (gc05a2->link_freq)
+		gc05a2->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	gc05a2->pixel_rate =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc05a2_ctrl_ops,
+				  V4L2_CID_PIXEL_RATE, 0,
+				  gc05a2_to_pixel_rate(0),
+				  1,
+				  gc05a2_to_pixel_rate(0));
+
+	gc05a2->vblank =
+		v4l2_ctrl_new_std(ctrl_hdlr,
+				  &gc05a2_ctrl_ops, V4L2_CID_VBLANK,
+				  mode->vts_min - mode->height,
+				  GC05A2_VTS_MAX - mode->height, 1,
+				  mode->vts_def - mode->height);
+
+	h_blank = mode->hts - mode->width;
+	gc05a2->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					   V4L2_CID_HBLANK, h_blank, h_blank, 1,
+					   h_blank);
+	if (gc05a2->hblank)
+		gc05a2->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+	v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+			  V4L2_CID_ANALOGUE_GAIN, GC05A2_AGAIN_MIN,
+			  GC05A2_AGAIN_MAX, GC05A2_AGAIN_STEP,
+			  GC05A2_AGAIN_MIN);
+
+	exposure_max = mode->vts_def - GC05A2_EXP_MARGIN;
+	gc05a2->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &gc05a2_ctrl_ops,
+					     V4L2_CID_EXPOSURE, GC05A2_EXP_MIN,
+					     exposure_max, GC05A2_EXP_STEP,
+					     exposure_max);
+
+	v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &gc05a2_ctrl_ops,
+				     V4L2_CID_TEST_PATTERN,
+				     ARRAY_SIZE(gc05a2_test_pattern_menu) - 1,
+				     0, 0, gc05a2_test_pattern_menu);
+
+	/* register properties to fwnode (e.g. rotation, orientation) */
+	ret = v4l2_fwnode_device_parse(&client->dev, &props);
+	if (ret)
+		goto error_ctrls;
+
+	ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, ops, &props);
+	if (ret)
+		goto error_ctrls;
+
+	if (ctrl_hdlr->error) {
+		ret = ctrl_hdlr->error;
+		goto error_ctrls;
+	}
+
+	gc05a2->sd.ctrl_handler = ctrl_hdlr;
+
+	return 0;
+
+error_ctrls:
+	v4l2_ctrl_handler_free(ctrl_hdlr);
+
+	return ret;
+}
+
+static int gc05a2_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	struct gc05a2 *gc05a2;
+	int ret;
+
+	gc05a2 = devm_kzalloc(dev, sizeof(*gc05a2), GFP_KERNEL);
+	if (!gc05a2)
+		return -ENOMEM;
+
+	gc05a2->dev = dev;
+
+	ret = gc05a2_parse_fwnode(gc05a2);
+	if (ret)
+		return ret;
+
+	gc05a2->regmap = devm_cci_regmap_init_i2c(client, 16);
+	if (IS_ERR(gc05a2->regmap))
+		return dev_err_probe(dev, PTR_ERR(gc05a2->regmap),
+				     "failed to init CCI\n");
+
+	gc05a2->xclk = devm_clk_get(dev, NULL);
+	if (IS_ERR(gc05a2->xclk))
+		return dev_err_probe(dev, PTR_ERR(gc05a2->xclk),
+				     "failed to get xclk\n");
+
+	ret = clk_set_rate(gc05a2->xclk, GC05A2_DEFAULT_CLK_FREQ);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to set xclk frequency\n");
+
+	ret = gc05a2_get_regulators(dev, gc05a2);
+	if (ret < 0)
+		return dev_err_probe(dev, ret,
+				     "failed to get regulators\n");
+
+	gc05a2->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(gc05a2->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(gc05a2->reset_gpio),
+				     "failed to get gpio\n");
+
+	v4l2_i2c_subdev_init(&gc05a2->sd, client, &gc05a2_subdev_ops);
+	gc05a2->sd.internal_ops = &gc05a2_internal_ops;
+	gc05a2->cur_mode = &gc05a2_modes[0];
+
+	ret = gc05a2_init_controls(gc05a2);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to init controls\n");
+
+	gc05a2->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+			    V4L2_SUBDEV_FL_HAS_EVENTS;
+	gc05a2->pad.flags = MEDIA_PAD_FL_SOURCE;
+	gc05a2->sd.dev = &client->dev;
+	gc05a2->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+
+	ret = media_entity_pads_init(&gc05a2->sd.entity, 1, &gc05a2->pad);
+	if (ret < 0) {
+		dev_err(dev, "could not register media entity\n");
+		goto err_v4l2_ctrl_handler_free;
+	}
+
+	gc05a2->sd.state_lock = gc05a2->ctrls.lock;
+	ret = v4l2_subdev_init_finalize(&gc05a2->sd);
+	if (ret < 0) {
+		dev_err(dev, "v4l2 subdev init error: %d\n", ret);
+		goto err_media_entity_cleanup;
+	}
+
+	pm_runtime_set_active(gc05a2->dev);
+	pm_runtime_enable(gc05a2->dev);
+	pm_runtime_set_autosuspend_delay(gc05a2->dev, 1000);
+	pm_runtime_use_autosuspend(gc05a2->dev);
+	pm_runtime_idle(gc05a2->dev);
+
+	ret = v4l2_async_register_subdev_sensor(&gc05a2->sd);
+	if (ret < 0) {
+		dev_err(dev, "could not register v4l2 device\n");
+		goto err_rpm;
+	}
+
+	return 0;
+
+err_rpm:
+	pm_runtime_disable(gc05a2->dev);
+	v4l2_subdev_cleanup(&gc05a2->sd);
+
+err_media_entity_cleanup:
+	media_entity_cleanup(&gc05a2->sd.entity);
+
+err_v4l2_ctrl_handler_free:
+	v4l2_ctrl_handler_free(&gc05a2->ctrls);
+
+	return ret;
+}
+
+static void gc05a2_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct gc05a2 *gc05a2 = to_gc05a2(sd);
+
+	v4l2_async_unregister_subdev(&gc05a2->sd);
+	v4l2_subdev_cleanup(sd);
+	media_entity_cleanup(&gc05a2->sd.entity);
+	v4l2_ctrl_handler_free(&gc05a2->ctrls);
+
+	pm_runtime_disable(&client->dev);
+	if (!pm_runtime_status_suspended(&client->dev))
+		gc05a2_power_off(gc05a2->dev);
+	pm_runtime_set_suspended(&client->dev);
+}
+
+static const struct of_device_id gc05a2_of_match[] = {
+	{ .compatible = "galaxycore,gc05a2" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, gc05a2_of_match);
+
+static DEFINE_RUNTIME_DEV_PM_OPS(gc05a2_pm_ops,
+				 gc05a2_power_off,
+				 gc05a2_power_on,
+				 NULL);
+
+static struct i2c_driver gc05a2_i2c_driver = {
+	.driver = {
+		.of_match_table = gc05a2_of_match,
+		.pm = pm_ptr(&gc05a2_pm_ops),
+		.name  = "gc05a2",
+	},
+	.probe = gc05a2_probe,
+	.remove = gc05a2_remove,
+};
+module_i2c_driver(gc05a2_i2c_driver);
+
+MODULE_DESCRIPTION("GalaxyCore gc05a2 Camera driver");
+MODULE_AUTHOR("Zhi Mao <zhi.mao@mediatek.com>");
+MODULE_LICENSE("GPL");
-- 
2.25.1


^ permalink raw reply related

* [PATCH v3 1/2] media: dt-bindings: i2c: add GalaxyCore GC05A2 image sensor
From: Zhi Mao @ 2024-04-03  3:38 UTC (permalink / raw)
  To: mchehab, robh+dt, krzysztof.kozlowski+dt, sakari.ailus
  Cc: laurent.pinchart, shengnan.wang, yaya.chang,
	Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
	matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
	10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
	linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
	andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek,
	Krzysztof Kozlowski
In-Reply-To: <20240403033825.9072-1-zhi.mao@mediatek.com>

Add YAML device tree binding for GC05A2 CMOS image sensor,
and the relevant MAINTAINERS entries.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Zhi Mao <zhi.mao@mediatek.com>
---
 .../bindings/media/i2c/galaxycore,gc05a2.yaml | 112 ++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml

diff --git a/Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml
new file mode 100644
index 000000000000..0e7a7b5ac89f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (c) 2023 MediaTek Inc.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/galaxycore,gc05a2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GalaxyCore gc05a2 1/5" 5M Pixel MIPI CSI-2 sensor
+
+maintainers:
+  - Zhi Mao <zhi.mao@mediatek.com>
+
+description:
+  The gc05a2 is a raw image sensor with an MIPI CSI-2 image data
+  interface and CCI (I2C compatible) control bus. The output format
+  is raw Bayer.
+
+properties:
+  compatible:
+    const: galaxycore,gc05a2
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  dovdd-supply: true
+
+  avdd-supply: true
+
+  dvdd-supply: true
+
+  reset-gpios:
+    description: Reference to the GPIO connected to the RESETB pin.
+    maxItems: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/$defs/port-base
+    additionalProperties: false
+    description:
+      Output port node, single endpoint describing the CSI-2 transmitter.
+
+    properties:
+      endpoint:
+        $ref: /schemas/media/video-interfaces.yaml#
+        unevaluatedProperties: false
+
+        properties:
+          data-lanes:
+            oneOf:
+              - items:
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
+              - items:
+                  - const: 1
+                  - const: 2
+
+          link-frequencies: true
+
+        required:
+          - data-lanes
+          - link-frequencies
+
+    required:
+      - endpoint
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - dovdd-supply
+  - avdd-supply
+  - dvdd-supply
+  - reset-gpios
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        sensor@37 {
+            compatible =  "galaxycore,gc05a2";
+            reg = <0x37>;
+
+            clocks = <&gc05a2_clk>;
+
+            reset-gpios = <&pio 21 GPIO_ACTIVE_LOW>;
+
+            avdd-supply = <&gc05a2_avdd>;
+            dovdd-supply = <&gc05a2_dovdd>;
+            dvdd-supply = <&gc05a2_dvdd>;
+
+            port {
+                sensor_out: endpoint {
+                    data-lanes = <1 2>;
+                    link-frequencies = /bits/ 64 <448000000 224000000>;
+                    remote-endpoint = <&seninf_csi_port_1_in>;
+                };
+            };
+        };
+    };
+
+...
-- 
2.25.1


^ permalink raw reply related

* [PATCH v3 0/2]  media: i2c: Add support for GC05A2 sensor
From: Zhi Mao @ 2024-04-03  3:38 UTC (permalink / raw)
  To: mchehab, robh+dt, krzysztof.kozlowski+dt, sakari.ailus
  Cc: laurent.pinchart, shengnan.wang, yaya.chang,
	Project_Global_Chrome_Upstream_Group, yunkec, conor+dt,
	matthias.bgg, angelogioacchino.delregno, jacopo.mondi, zhi.mao,
	10572168, hverkuil-cisco, heiko, jernej.skrabec, macromorgan,
	linus.walleij, hdegoede, tomi.valkeinen, gerald.loacker,
	andy.shevchenko, bingbu.cao, dan.scally, linux-media, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek

This series adds YAML DT binding and V4L2 sub-device driver for Galaxycore's
GC05A2 5-megapixel 10-bit RAW CMOS 1/5" sensor, with an MIPI CSI-2 image data
interface and the I2C control bus.

The driver is implemented with V4L2 framework.
 - Async registered as a V4L2 sub-device.
 - As the first component of camera system including Seninf, ISP pipeline.
 - A media entity that provides one source pad in common.
 - Used in camera features on ChromeOS application.

Also this driver supports following features:
 - manual exposure and analog gain control support
 - vertical blanking control support
 - test pattern support
 - media controller support
 - runtime PM support
 - support resolution: 2592x1944@30fps, 1280x720@60fps

Previous versions of this patch-set can be found here:
v2:https://lore.kernel.org/linux-media/20240323014751.4989-1-zhi.mao@mediatek.com/
v1:https://lore.kernel.org/linux-media/20240316025253.2300-1-zhi.mao@mediatek.com/
v0:https://lore.kernel.org/linux-media/20240313054409.8073-1-zhi.mao@mediatek.com/

This series is based on linux-next, tag: next-20240402
Changes in v3:
- gc05a2 sensor driver:
-- remove gc05a2_power_on() in function:probe(),
   and use pm_runtime_resume_and_get() to power on sensor in function:start_streaming()
-- move gc05a2_identify_module() frome function:probe() to function:start_streaming()

Thanks

Zhi Mao (2):
  media: dt-bindings: i2c: add GalaxyCore GC05A2 image sensor
  media: i2c: Add GC05A2 image sensor driver

 .../bindings/media/i2c/galaxycore,gc05a2.yaml |  112 ++
 drivers/media/i2c/Kconfig                     |   10 +
 drivers/media/i2c/Makefile                    |    1 +
 drivers/media/i2c/gc05a2.c                    | 1383 +++++++++++++++++
 4 files changed, 1506 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/i2c/galaxycore,gc05a2.yaml
 create mode 100644 drivers/media/i2c/gc05a2.c

-- 
2.25.1





^ permalink raw reply

* [PATCH] arm64: dts: qcom: qcs6490-rb3gen2: Specify zap region for gpu
From: Bjorn Andersson @ 2024-04-03  3:33 UTC (permalink / raw)
  To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Caleb Connolly, Komal Bajaj, Naina Mehta
  Cc: linux-arm-msm, devicetree, linux-kernel, Bjorn Andersson

Without the zap region defined the enabled GPU will, if able to find the
other firmware files, attempt to initialize itself without the zap
firmware loading, which causes the rb3gen2 to freeze or crash.

Add the zap-shader node and define the memory-region and firmware path
to avoid this problem.

Fixes: 04cf333afc75 ("arm64: dts: qcom: Add base qcs6490-rb3gen2 board dts")
Signed-off-by: Bjorn Andersson <quic_bjorande@quicinc.com>
---
 arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
index 63ebe0774f1d..5b81b5e0b4ce 100644
--- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -471,6 +471,13 @@ &gcc {
 			   <GCC_WPSS_RSCP_CLK>;
 };
 
+&gpu {
+	zap-shader {
+		memory-region = <&gpu_microcode_mem>;
+		firmware-name = "qcom/qcs6490/a660_zap.mbn";
+	};
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };

---
base-commit: 727900b675b749c40ba1f6669c7ae5eb7eb8e837
change-id: 20240326-rb3gen2-gpu-4343c5dc7e40

Best regards,
-- 
Bjorn Andersson <quic_bjorande@quicinc.com>


^ permalink raw reply related

* Re: [PATCH 3/3] ARM: dts: Modify I2C bus configuration
From: Andrew Jeffery @ 2024-04-03  3:30 UTC (permalink / raw)
  To: Renze Nicolai, linux-arm-kernel, devicetree, linux-kernel,
	linux-aspeed, arnd, olof, soc, robh+dt, krzysztof.kozlowski+dt,
	joel, andrew
In-Reply-To: <20240329130152.878944-4-renze@rnplus.nl>

Hi Renze,

On Fri, 2024-03-29 at 14:01 +0100, Renze Nicolai wrote:
> This commit enables I2C bus 8 which is exposed on the IPMB_1 connector on the X570D4U mainboard.
> Additionally it adds a descriptive comment to I2C busses 1 and 5.

checkpatch on this one too :)

Cheers,

Andrew

^ permalink raw reply

* Re: [PATCH 2/3] ARM: dts: Disable unused ADC channels for Asrock X570D4U BMC
From: Andrew Jeffery @ 2024-04-03  3:29 UTC (permalink / raw)
  To: Renze Nicolai, linux-arm-kernel, devicetree, linux-kernel,
	linux-aspeed, arnd, olof, soc, robh+dt, krzysztof.kozlowski+dt,
	joel, andrew
In-Reply-To: <20240329130152.878944-3-renze@rnplus.nl>

Hi Renze,

On Fri, 2024-03-29 at 14:01 +0100, Renze Nicolai wrote:
> This commit disables unused ADC channels and labels the ADC channels used with their function.

Please run this through checkpatch and address the warnings.

Also, the submitting patches documentation[1] suggests using the
imperative mood - instead of "This commit disables ...", use "Disable
...". The change subject is phrased the expected way.

[1]: https://docs.kernel.org/process/submitting-patches.html

Taking the subject and the description together, the description feels
a little redundant. Maybe it could be trimmed back to

> Also, label the ADC channels used with their function.

Andrew


^ permalink raw reply

* Re: [PATCH 1/3] ARM: dts: Modify GPIO table for Asrock X570D4U BMC
From: Andrew Jeffery @ 2024-04-03  3:21 UTC (permalink / raw)
  To: Renze Nicolai, linux-arm-kernel, devicetree, linux-kernel,
	linux-aspeed, arnd, olof, soc, robh+dt, krzysztof.kozlowski+dt,
	joel, andrew
In-Reply-To: <20240329130152.878944-2-renze@rnplus.nl>

Hi Renze,

Do you mind running this patch and the others in the series through
./scripts/checkpatch.pl? Generally patches sent to the list should not
generate warnings.

It looks like these patches are generated against Joel's bmc/for-next
branch. He's applied your original X570D4U devicetree patch there,
(though that also causes checkpatch warnings).

On Fri, 2024-03-29 at 14:01 +0100, Renze Nicolai wrote:
> This commit removes button-nmi-n, this board does not have support for an NMI button.
> Input status-locatorled-n has been renamed to input-locatorled-n to better indicate the signal type.
> The suffix -n has been appended to the name of control-locatorbutton, button-power, control-power, button-reset, control-reset, input-id0, input-id1, input-id2, output-bmc-ready to reflect the inverted signal polarity.
> GPIO output-rtc-battery-voltage-read-enable has been renamed to output-hwm-vbat-enable, input-alert1-n to input-aux-smb-alert-n, input-alert3-n to input-psu-smb-alert-n, input-mfg to input-mfg-mode-n and input-caseopen to input-case-open-n.
> And GPIOs input-bmc-smb-present-n, input-pcie-wake-n, input-sleep-s3-n, input-sleep-s5-n and input-power-good have been added.
> 

For instance, checkpatch warns about these lines in the commit message
being too long. They should be wrapped at 72 characters.

Additionally, the description forms a bit of a list of things the patch
is doing. Patches are easier to review when they only do one thing, as
it removes the need to assess whether there are subtle interactions
between the several things, and if so, whether they're expected and
correct.

I'd prefer this change be split up so there's no need for such
concerns.

> Signed-off-by: Renze Nicolai <renze@rnplus.nl>
> ---
>  .../dts/aspeed/aspeed-bmc-asrock-x570d4u.dts  | 116 +++++++++---------
>  1 file changed, 58 insertions(+), 58 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
> index 3c975bc41ae7..34bc382bf492 100644
> --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
> +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-asrock-x570d4u.dts
> @@ -79,64 +79,64 @@ iio-hwmon {
>  &gpio {
>  	status = "okay";
>  	gpio-line-names =
> -	/*A0-A3*/       "status-locatorled-n",                    "",                      "button-nmi-n",          "",
> -	/*A4-A7*/       "",                                       "",                      "",                      "",
> -	/*B0-B3*/       "input-bios-post-cmplt-n",                "",                      "",                      "",
> -	/*B4-B7*/       "",                                       "",                      "",                      "",
> -	/*C0-C3*/       "",                                       "",                      "",                      "",
> -	/*C4-C7*/       "",                                       "",                      "control-locatorbutton", "",
> -	/*D0-D3*/       "button-power",                           "control-power",         "button-reset",          "control-reset",
> -	/*D4-D7*/       "",                                       "",                      "",                      "",
> -	/*E0-E3*/       "",                                       "",                      "",                      "",
> -	/*E4-E7*/       "",                                       "",                      "",                      "",
> -	/*F0-F3*/       "",                                       "",                      "",                      "",
> -	/*F4-F7*/       "",                                       "",                      "",                      "",
> -	/*G0-G3*/       "output-rtc-battery-voltage-read-enable", "input-id0",             "input-id1",             "input-id2",
> -	/*G4-G7*/       "input-alert1-n",                         "input-alert2-n",        "input-alert3-n",        "",
> -	/*H0-H3*/       "",                                       "",                      "",                      "",
> -	/*H4-H7*/       "input-mfg",                              "",                      "led-heartbeat-n",       "input-caseopen",
> -	/*I0-I3*/       "",                                       "",                      "",                      "",
> -	/*I4-I7*/       "",                                       "",                      "",                      "",
> -	/*J0-J3*/       "output-bmc-ready",                       "",                      "",                      "",
> -	/*J4-J7*/       "",                                       "",                      "",                      "",
> -	/*K0-K3*/       "",                                       "",                      "",                      "",
> -	/*K4-K7*/       "",                                       "",                      "",                      "",
> -	/*L0-L3*/       "",                                       "",                      "",                      "",
> -	/*L4-L7*/       "",                                       "",                      "",                      "",
> -	/*M0-M3*/       "",                                       "",                      "",                      "",
> -	/*M4-M7*/       "",                                       "",                      "",                      "",
> -	/*N0-N3*/       "",                                       "",                      "",                      "",
> -	/*N4-N7*/       "",                                       "",                      "",                      "",
> -	/*O0-O3*/       "",                                       "",                      "",                      "",
> -	/*O4-O7*/       "",                                       "",                      "",                      "",
> -	/*P0-P3*/       "",                                       "",                      "",                      "",
> -	/*P4-P7*/       "",                                       "",                      "",                      "",
> -	/*Q0-Q3*/       "",                                       "",                      "",                      "",
> -	/*Q4-Q7*/       "",                                       "",                      "",                      "",
> -	/*R0-R3*/       "",                                       "",                      "",                      "",
> -	/*R4-R7*/       "",                                       "",                      "",                      "",
> -	/*S0-S3*/       "input-bmc-pchhot-n",                     "",                      "",                      "",
> -	/*S4-S7*/       "",                                       "",                      "",                      "",
> -	/*T0-T3*/       "",                                       "",                      "",                      "",
> -	/*T4-T7*/       "",                                       "",                      "",                      "",
> -	/*U0-U3*/       "",                                       "",                      "",                      "",
> -	/*U4-U7*/       "",                                       "",                      "",                      "",
> -	/*V0-V3*/       "",                                       "",                      "",                      "",
> -	/*V4-V7*/       "",                                       "",                      "",                      "",
> -	/*W0-W3*/       "",                                       "",                      "",                      "",
> -	/*W4-W7*/       "",                                       "",                      "",                      "",
> -	/*X0-X3*/       "",                                       "",                      "",                      "",
> -	/*X4-X7*/       "",                                       "",                      "",                      "",
> -	/*Y0-Y3*/       "",                                       "",                      "",                      "",
> -	/*Y4-Y7*/       "",                                       "",                      "",                      "",
> -	/*Z0-Z3*/       "",                                       "",                      "led-fault-n",           "output-bmc-throttle-n",
> -	/*Z4-Z7*/       "",                                       "",                      "",                      "",
> -	/*AA0-AA3*/     "input-cpu1-thermtrip-latch-n",           "",                      "input-cpu1-prochot-n",  "",
> -	/*AA4-AC7*/     "",                                       "",                      "",                      "",
> -	/*AB0-AB3*/     "",                                       "",                      "",                      "",
> -	/*AB4-AC7*/     "",                                       "",                      "",                      "",
> -	/*AC0-AC3*/     "",                                       "",                      "",                      "",
> -	/*AC4-AC7*/     "",                                       "",                      "",                      "";
> +	/*A0-A3*/       "input-locatorled-n",                     "",                      "",                        "",
> +	/*A4-A7*/       "",                                       "",                      "",                        "",
> +	/*B0-B3*/       "input-bios-post-cmplt-n",                "",                      "",                        "",
> +	/*B4-B7*/       "",                                       "",                      "",                        "",
> +	/*C0-C3*/       "",                                       "",                      "",                        "",
> +	/*C4-C7*/       "",                                       "",                      "control-locatorbutton-n", "",
> +	/*D0-D3*/       "button-power-n",                         "control-power-n",       "button-reset-n",          "control-reset-n",
> +	/*D4-D7*/       "",                                       "",                      "",                        "",
> +	/*E0-E3*/       "",                                       "",                      "",                        "",
> +	/*E4-E7*/       "",                                       "",                      "",                        "",
> +	/*F0-F3*/       "",                                       "",                      "",                        "",
> +	/*F4-F7*/       "",                                       "",                      "",                        "",
> +	/*G0-G3*/       "output-hwm-vbat-enable",                 "input-id0-n",           "input-id1-n",             "input-id2-n",
> +	/*G4-G7*/       "input-aux-smb-alert-n",                  "",                      "input-psu-smb-alert-n",   "",
> +	/*H0-H3*/       "",                                       "",                      "",                        "",
> +	/*H4-H7*/       "input-mfg-mode-n",                       "",                      "led-heartbeat-n",         "input-case-open-n",
> +	/*I0-I3*/       "",                                       "",                      "",                        "",
> +	/*I4-I7*/       "",                                       "",                      "",                        "",
> +	/*J0-J3*/       "output-bmc-ready-n",                     "",                      "",                        "",
> +	/*J4-J7*/       "",                                       "",                      "",                        "",
> +	/*K0-K3*/       "",                                       "",                      "",                        "",
> +	/*K4-K7*/       "",                                       "",                      "",                        "",
> +	/*L0-L3*/       "",                                       "",                      "",                        "",
> +	/*L4-L7*/       "",                                       "",                      "",                        "",
> +	/*M0-M3*/       "",                                       "",                      "",                        "",
> +	/*M4-M7*/       "",                                       "",                      "",                        "",
> +	/*N0-N3*/       "",                                       "",                      "",                        "",
> +	/*N4-N7*/       "",                                       "",                      "",                        "",
> +	/*O0-O3*/       "",                                       "",                      "",                        "",
> +	/*O4-O7*/       "",                                       "",                      "",                        "",
> +	/*P0-P3*/       "",                                       "",                      "",                        "",
> +	/*P4-P7*/       "",                                       "",                      "",                        "",
> +	/*Q0-Q3*/       "",                                       "",                      "",                        "",
> +	/*Q4-Q7*/       "input-bmc-smb-present-n",                "",                      "",                        "input-pcie-wake-n",
> +	/*R0-R3*/       "",                                       "",                      "",                        "",
> +	/*R4-R7*/       "",                                       "",                      "",                        "",
> +	/*S0-S3*/       "input-bmc-pchhot-n",                     "",                      "",                        "",
> +	/*S4-S7*/       "",                                       "",                      "",                        "",
> +	/*T0-T3*/       "",                                       "",                      "",                        "",
> +	/*T4-T7*/       "",                                       "",                      "",                        "",
> +	/*U0-U3*/       "",                                       "",                      "",                        "",
> +	/*U4-U7*/       "",                                       "",                      "",                        "",
> +	/*V0-V3*/       "",                                       "",                      "",                        "",
> +	/*V4-V7*/       "",                                       "",                      "",                        "",
> +	/*W0-W3*/       "",                                       "",                      "",                        "",
> +	/*W4-W7*/       "",                                       "",                      "",                        "",
> +	/*X0-X3*/       "",                                       "",                      "",                        "",
> +	/*X4-X7*/       "",                                       "",                      "",                        "",
> +	/*Y0-Y3*/       "input-sleep-s3-n",                       "input-sleep-s5-n",      "",                        "",
> +	/*Y4-Y7*/       "",                                       "",                      "",                        "",
> +	/*Z0-Z3*/       "",                                       "",                      "led-fault-n",             "output-bmc-throttle-n",
> +	/*Z4-Z7*/       "",                                       "",                      "",                        "",
> +	/*AA0-AA3*/     "input-cpu1-thermtrip-latch-n",           "",                      "input-cpu1-prochot-n",    "",
> +	/*AA4-AC7*/     "",                                       "",                      "",                        "",
> +	/*AB0-AB3*/     "",                                       "input-power-good",      "",                        "",
> +	/*AB4-AC7*/     "",                                       "",                      "",                        "",
> +	/*AC0-AC3*/     "",                                       "",                      "",                        "",
> +	/*AC4-AC7*/     "",                                       "",                      "",                        "";
>  };
>  

I'd like some discussion in the commit message of whether these names
align with net names in the schematic, follow the OpenBMC GPIO naming
guidelines, or use some other strategy entirely.

Also, the columnisation of the names leads to more warnings from
checkpatch (due to line length). Other Aspeed-based devicetrees tend
not to make the whitespace so significant, and generally group the
GPIOs by complete banks. I prefer that the X570D4U devicetree is
consistent with the others.

Andrew

^ permalink raw reply

* Re: [PATCH v1 1/5] dt-bindings: pwm: Add Loongson PWM controller
From: Binbin Zhou @ 2024-04-03  3:16 UTC (permalink / raw)
  To: Rob Herring
  Cc: Binbin Zhou, Huacai Chen, Uwe Kleine-König,
	Krzysztof Kozlowski, Conor Dooley, Huacai Chen, loongson-kernel,
	linux-pwm, devicetree, Xuerui Wang, loongarch
In-Reply-To: <CAMpQs4K_VSqdm7x=cSyMTBYQyOm=th0YrYKdZ74dp35hyRBXgQ@mail.gmail.com>

On Wed, Apr 3, 2024 at 8:37 AM Binbin Zhou <zhoubb.aaron@gmail.com> wrote:
>
> Hi Rob:
>
> Thanks for your reply.
>
> On Tue, Apr 2, 2024 at 11:40 PM Rob Herring <robh@kernel.org> wrote:
> >
> > On Tue, Apr 02, 2024 at 03:58:38PM +0800, Binbin Zhou wrote:
> > > Add Loongson PWM controller binding with DT schema format using
> > > json-schema.
> > >
> > > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > > ---
> > >  .../devicetree/bindings/pwm/pwm-loongson.yaml | 64 +++++++++++++++++++
> >
> > Filename should match compatible.
>
> Emm... How about renaming it as loongson, pwm.yaml?
>
> >
> > >  MAINTAINERS                                   |  6 ++
> > >  2 files changed, 70 insertions(+)
> > >  create mode 100644 Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml b/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
> > > new file mode 100644
> > > index 000000000000..d25904468353
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
> > > @@ -0,0 +1,64 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: http://devicetree.org/schemas/pwm/pwm-loongson.yaml#
> > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > +
> > > +title: Loongson PWM Controller
> > > +
> > > +maintainers:
> > > +  - Binbin Zhou <zhoubinbin@loongson.cn>
> > > +
> > > +description:
> > > +  It is the generic PWM framework driver for Loongson family.
> >
> > That's describing the driver. Not really relevant to the binding.
> >
> Ok ,I will rewrite this part.
>
> >
> > > +  Each PWM has one pulse width output signal and one pulse input
> > > +  signal to be measured.
> > > +  It can be found on Loongson-2K series cpus and Loongson LS7A bridge chips.
> > > +
> > > +allOf:
> > > +  - $ref: pwm.yaml#
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - const: loongson,ls7a-pwm
> > > +      - items:
> > > +          - enum:
> > > +              - loongson,ls2k0500-pwm
> > > +              - loongson,ls2k1000-pwm
> > > +              - loongson,ls2k2000-pwm
> > > +          - const: loongson,ls7a-pwm
> > > +
> > > +  reg:
> > > +    maxItems: 1
> > > +
> > > +  interrupts:
> > > +    maxItems: 1
> > > +
> > > +  clocks:
> > > +    maxItems: 1
> > > +
> > > +  '#pwm-cells':
> > > +    const: 3
> >
> > Please define what is in each cell. If there's only 2 signals, then the
> > first cell defines the output or input (what value for which one?).

Hi Rob:

Sorry, the previous email did not answer this question.
The first cell defines the output signal, and its value is 0.

Thanks.
Binbin
> >
> > Really, the PWM binding is only for outputs, so is a cell even needed? I
> > suppose we could use it for inputs too, but that's really "input
> > capture" type operation that timers often have. I'll defer to the PWM
> > maintainers...
>
> Ok, I will try to add some description about it.
>
> If I understand correctly, the meaning of each cell in "#pwm-cells"is
> determined.
> The first cell specifies the per-chip index of the PWM to use, the
> second cell is the period in nanoseconds and the third cell is the
> polarity.
>
> >
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - interrupts
> > > +  - clocks
> > > +  - '#pwm-cells'
> >
> > pwm.yaml makes this required already.
> >
> Yes, this is unnecessary. I will drop it in the next version.
>
> Thanks.
> Binbin
> > Rob
> >

^ permalink raw reply

* Re: [PATCH 1/7] arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
From: Frank Li @ 2024-04-03  3:10 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Fabio Estevam, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Shawn Guo, Sascha Hauer, Pengutronix Kernel Team, NXP Linux Team,
	Marcel Ziswiler, Philippe Schenker, Max Krummenacher,
	Alexander Stein, Joakim Zhang, devicetree, linux-arm-kernel,
	linux-kernel, stable
In-Reply-To: <ZgyzxmuMIK87C2nW@dragon>

On Wed, Apr 03, 2024 at 09:41:26AM +0800, Shawn Guo wrote:
> On Tue, Apr 02, 2024 at 11:09:17AM -0400, Frank Li wrote:
> > On Mon, Apr 01, 2024 at 08:04:56PM -0300, Fabio Estevam wrote:
> > > On Mon, Apr 1, 2024 at 7:25 PM Frank Li <Frank.Li@nxp.com> wrote:
> > > >
> > > > lpcg's arg0 should use clock indices instead of index.
> > > >
> > > > pwm0_lpcg: clock-controller@5d400000 {
> > > >         ...                                                // Col1  Col2
> > > >         clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 0     0
> > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 1     1
> > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>,  // 2     4
> > > >                  <&lsio_bus_clk>,                          // 3     5
> > > >                  <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;  // 4     6
> > > >         clock-indices = <IMX_LPCG_CLK_0>, <IMX_LPCG_CLK_1>,
> > > >                         <IMX_LPCG_CLK_4>, <IMX_LPCG_CLK_5>,
> > > >                         <IMX_LPCG_CLK_6>;
> > > > };
> > > >
> > > > Col1: index, which exited dts try to get.
> > > 
> > > I cannot understand this sentence, sorry.
> > 
> > This base on downstream dts code.  Downstream code use index in 'Col1' to
> > get clock.
> 
> So s/exited/existing you meant?

Yes, sorry for typo. 

Frank

> 
> Shawn
> 

^ permalink raw reply

* Re: [PATCH net-next] dt-bindings: net: snps,dwmac: Align 'snps,priority' type definition
From: patchwork-bot+netdevbpf @ 2024-04-03  2:40 UTC (permalink / raw)
  To: Rob Herring
  Cc: davem, edumazet, kuba, pabeni, krzysztof.kozlowski+dt, conor+dt,
	alexandre.torgue, peppe.cavallaro, joabreu, netdev, devicetree,
	linux-kernel
In-Reply-To: <20240401204422.1692359-2-robh@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon,  1 Apr 2024 15:44:22 -0500 you wrote:
> 'snps,priority' is also defined in dma/snps,dw-axi-dmac.yaml as a
> uint32-array. It's preferred to have a single type for a given property
> name, so update the type in snps,dwmac schema to match.
> 
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
>  Documentation/devicetree/bindings/net/snps,dwmac.yaml | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)

Here is the summary with links:
  - [net-next] dt-bindings: net: snps,dwmac: Align 'snps,priority' type definition
    https://git.kernel.org/netdev/net-next/c/992c287d8778

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH v1 1/5] dt-bindings: pwm: Add Loongson PWM controller
From: Binbin Zhou @ 2024-04-03  2:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: Binbin Zhou, Huacai Chen, Uwe Kleine-König,
	Krzysztof Kozlowski, Conor Dooley, Huacai Chen, loongson-kernel,
	linux-pwm, devicetree, Xuerui Wang, loongarch
In-Reply-To: <20240402174051.GA324804-robh@kernel.org>

Hi Rob:

Thanks for your reply.

On Tue, Apr 2, 2024 at 11:40 PM Rob Herring <robh@kernel.org> wrote:
>
> On Tue, Apr 02, 2024 at 03:58:38PM +0800, Binbin Zhou wrote:
> > Add Loongson PWM controller binding with DT schema format using
> > json-schema.
> >
> > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > ---
> >  .../devicetree/bindings/pwm/pwm-loongson.yaml | 64 +++++++++++++++++++
>
> Filename should match compatible.

Emm... How about renaming it as loongson, pwm.yaml?

>
> >  MAINTAINERS                                   |  6 ++
> >  2 files changed, 70 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml b/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
> > new file mode 100644
> > index 000000000000..d25904468353
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/pwm/pwm-loongson.yaml
> > @@ -0,0 +1,64 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/pwm/pwm-loongson.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Loongson PWM Controller
> > +
> > +maintainers:
> > +  - Binbin Zhou <zhoubinbin@loongson.cn>
> > +
> > +description:
> > +  It is the generic PWM framework driver for Loongson family.
>
> That's describing the driver. Not really relevant to the binding.
>
Ok ,I will rewrite this part.

>
> > +  Each PWM has one pulse width output signal and one pulse input
> > +  signal to be measured.
> > +  It can be found on Loongson-2K series cpus and Loongson LS7A bridge chips.
> > +
> > +allOf:
> > +  - $ref: pwm.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - const: loongson,ls7a-pwm
> > +      - items:
> > +          - enum:
> > +              - loongson,ls2k0500-pwm
> > +              - loongson,ls2k1000-pwm
> > +              - loongson,ls2k2000-pwm
> > +          - const: loongson,ls7a-pwm
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    maxItems: 1
> > +
> > +  '#pwm-cells':
> > +    const: 3
>
> Please define what is in each cell. If there's only 2 signals, then the
> first cell defines the output or input (what value for which one?).
>
> Really, the PWM binding is only for outputs, so is a cell even needed? I
> suppose we could use it for inputs too, but that's really "input
> capture" type operation that timers often have. I'll defer to the PWM
> maintainers...

Ok, I will try to add some description about it.

If I understand correctly, the meaning of each cell in "#pwm-cells"is
determined.
The first cell specifies the per-chip index of the PWM to use, the
second cell is the period in nanoseconds and the third cell is the
polarity.

>
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - '#pwm-cells'
>
> pwm.yaml makes this required already.
>
Yes, this is unnecessary. I will drop it in the next version.

Thanks.
Binbin
> Rob
>

^ permalink raw reply


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