* Re: [PATCH v6 04/16] dt-bindings: net: wireless: qcom,ath11k: describe the ath11k on QCA6390
From: Kalle Valo @ 2024-03-25 13:57 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Marcel Holtmann, Luiz Augusto von Dentz, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Konrad Dybcio,
Liam Girdwood, Mark Brown, Catalin Marinas, Will Deacon,
Bjorn Helgaas, Saravana Kannan, Geert Uytterhoeven, Arnd Bergmann,
Neil Armstrong, Marek Szyprowski, Alex Elder, Srini Kandagatla,
Greg Kroah-Hartman, Abel Vesa, Manivannan Sadhasivam,
Lukas Wunner, Dmitry Baryshkov, linux-bluetooth, netdev,
devicetree, linux-kernel, linux-wireless, linux-arm-msm,
linux-arm-kernel, linux-pci, linux-pm, Bartosz Golaszewski
In-Reply-To: <20240325131624.26023-5-brgl@bgdev.pl>
Bartosz Golaszewski <brgl@bgdev.pl> writes:
> From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
>
> Add a PCI compatible for the ATH11K module on QCA6390 and describe the
> power inputs from the PMU that it consumes.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
[...]
> +allOf:
> + - if:
> + properties:
> + compatible:
> + contains:
> + const: pci17cb,1101
> + then:
> + required:
> + - vddrfacmn-supply
> + - vddaon-supply
> + - vddwlcx-supply
> + - vddwlmx-supply
> + - vddrfa0p8-supply
> + - vddrfa1p2-supply
> + - vddrfa1p7-supply
> + - vddpcie0p9-supply
> + - vddpcie1p8-supply
I don't know DT well enough to know what the "required:" above means,
but does this take into account that there are normal "plug&play" type
of QCA6390 boards as well which don't need any DT settings?
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH v1 2/2] dt-bindings: clock: rockchip: Add support for clk input / output switch
From: Rob Herring @ 2024-03-25 13:55 UTC (permalink / raw)
To: Sugar Zhang
Cc: Stephen Boyd, Conor Dooley, linux-rockchip, linux-arm-kernel,
heiko, linux-clk, Michael Turquette, devicetree, linux-kernel,
Krzysztof Kozlowski
In-Reply-To: <1711340191-69588-2-git-send-email-sugar.zhang@rock-chips.com>
On Mon, 25 Mar 2024 12:16:30 +0800, Sugar Zhang wrote:
> This patch add support switch for clk-bidirection which located
> at GRF, such as SAIx_MCLK_{IN OUT} which share the same pin.
> and these config maybe located in many pieces of GRF,
> which hard to addressed in one single clk driver. so, we add
> this simple helper driver to address this situation.
>
> In order to simplify implement and usage, and also for safety
> clk usage (avoid high freq glitch), we set all clk out as disabled
> (which means Input default for clk-bidrection) in the pre-stage,
> such boot-loader or init by HW default. And then set a safety freq
> before enable clk-out, such as "assign-clock-rates" or clk_set_rate
> in drivers.
>
> e.g.
>
> 1. mclk{out,in}_sai0 define:
>
> mclkin_sai0: mclkin-sai0 {
> compatible = "fixed-clock";
> #clock-cells = <0>;
> clock-frequency = <12288000>;
> clock-output-names = "mclk_sai0_from_io";
> };
>
> mclkout_sai0: mclkout-sai0@ff040070 {
> compatible = "rockchip,clk-out";
> reg = <0 0xff040070 0 0x4>;
> clocks = <&cru MCLK_SAI0_OUT2IO>;
> #clock-cells = <0>;
> clock-output-names = "mclk_sai0_to_io";
> rockchip,bit-shift = <4>;
> //example with PD if reg access needed
> power-domains = <&power RK3562_PD_VO>;
> };
>
> Note:
>
> clock-output-names of mclkin_sai0 should equal to strings in drivers. such as:
>
> drivers/clk/rockchip/clk-rk3562.c:
> PNAME(clk_sai0_p) = { "clk_sai0_src", "clk_sai0_frac", "xin_osc0_half", "mclk_sai0_from_io" };
>
> 2. mclkout_sai0 usage:
>
> &ext_codec {
> clocks = <&mclkout_sai0>;
> clock-names = "mclk";
> assigned-clocks = <&mclkout_sai0>;
> assigned-clock-rates = <12288000>;
> pinctrl-names = "default";
> pinctrl-0 = <&i2s0m0_mclk>;
> };
>
> clk_summary on sai0 work:
>
> cat /sys/kernel/debug/clk/clk_summary | egrep "pll|sai0"
>
> clk_sai0_src 1 1 0 1188000000 0 0 50000
> clk_sai0_frac 1 1 0 12288000 0 0 50000
> clk_sai0 1 1 0 12288000 0 0 50000
> mclk_sai0 1 1 0 12288000 0 0 50000
> mclk_sai0_out2io 1 1 0 12288000 0 0 50000
> mclk_sai0_to_io 1 1 0 12288000 0 0 50000
>
> example with PD if reg access needed:
>
> * PD status when mclk_sai0_to_io on:
>
> cat /sys/kernel/debug/pm_genpd/pm_genpd_summary
>
> domain status children
> /device runtime status
> ----------------------------------------------------------------------
> ...
>
> vo on
> /devices/platform/clocks/ff040070.mclkout-sai0 active
> ...
>
> * PD status when mclk_sai0_to_io off:
>
> cat /sys/kernel/debug/pm_genpd/pm_genpd_summary
>
> domain status children
> /device runtime status
> ----------------------------------------------------------------------
> ...
>
> vo off-0
> /devices/platform/clocks/ff040070.mclkout-sai0 suspended
> ...
>
> 3. mclkin_sai0 usage:
>
> please override freq of mclkin as the real external clkin, such as:
>
> &mclkin_sai0 {
> clock-frequency = <24576000>;
> }
>
> &ext_codec {
> clocks = <&mclkin_sai0>;
> clock-names = "mclk";
> assigned-clocks = <&cru CLK_SAI0>;
> assigned-clock-parents = <&mclkin_sai0>;
> pinctrl-names = "default";
> pinctrl-0 = <&i2s0m0_mclk>;
> };
>
> clk_summary on sai0 work:
>
> cat /sys/kernel/debug/clk/clk_summary | egrep "pll|sai0"
>
> mclk_sai0_from_io 1 1 0 12288000 0 0 50000
> clk_sai0 1 1 0 12288000 0 0 50000
> mclk_sai0 1 1 0 12288000 0 0 50000
> mclk_sai0_out2io 0 0 0 12288000 0 0 50000
> mclk_sai0_to_io 0 0 0 12288000 0 0 50000
>
> Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
> ---
>
> .../bindings/clock/rockchip,clk-out.yaml | 107 +++++++++++++++++++++
> 1 file changed, 107 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/clock/rockchip,clk-out.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/clock/rockchip,clk-out.yaml: title: 'Rockchip Clock Out Control Module Binding' should not be valid under {'pattern': '([Bb]inding| [Ss]chema)'}
hint: Everything is a binding/schema, no need to say it. Describe what hardware the binding is for.
from schema $id: http://devicetree.org/meta-schemas/base.yaml#
Error: Documentation/devicetree/bindings/clock/rockchip,clk-out.example.dts:28.28-29 syntax error
FATAL ERROR: Unable to parse input tree
make[2]: *** [scripts/Makefile.lib:427: Documentation/devicetree/bindings/clock/rockchip,clk-out.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1430: dt_binding_check] Error 2
make: *** [Makefile:240: __sub-make] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/1711340191-69588-2-git-send-email-sugar.zhang@rock-chips.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: arm: qcom: Add Motorola Moto G (2013)
From: Rob Herring @ 2024-03-25 13:55 UTC (permalink / raw)
To: Stanislav Jakubek
Cc: Conor Dooley, Bjorn Andersson, linux-arm-kernel, linux-kernel,
phone-devel, linux-arm-msm, Krzysztof Kozlowski, Konrad Dybcio,
devicetree
In-Reply-To: <f5d4d71cd59f25b80889ef88fa044aa3a4268d46.1711288736.git.stano.jakubek@gmail.com>
On Sun, 24 Mar 2024 15:03:59 +0100, Stanislav Jakubek wrote:
> Document the Motorola Moto G (2013), which is a smartphone based
> on the Qualcomm MSM8226 SoC.
>
> Signed-off-by: Stanislav Jakubek <stano.jakubek@gmail.com>
> ---
> Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
New warnings running 'make CHECK_DTBS=y qcom/msm8226-motorola-falcon.dtb' for f5d4d71cd59f25b80889ef88fa044aa3a4268d46.1711288736.git.stano.jakubek@gmail.com:
arch/arm/boot/dts/qcom/msm8226-motorola-falcon.dtb: syscon@f9011000: compatible: 'anyOf' conditional failed, one must be fixed:
['syscon'] is too short
'syscon' is not one of ['allwinner,sun8i-a83t-system-controller', 'allwinner,sun8i-h3-system-controller', 'allwinner,sun8i-v3s-system-controller', 'allwinner,sun50i-a64-system-controller', 'amd,pensando-elba-syscon', 'brcm,cru-clkset', 'freecom,fsg-cs2-system-controller', 'fsl,imx93-aonmix-ns-syscfg', 'fsl,imx93-wakeupmix-syscfg', 'hisilicon,dsa-subctrl', 'hisilicon,hi6220-sramctrl', 'hisilicon,pcie-sas-subctrl', 'hisilicon,peri-subctrl', 'hpe,gxp-sysreg', 'intel,lgm-syscon', 'loongson,ls1b-syscon', 'loongson,ls1c-syscon', 'marvell,armada-3700-usb2-host-misc', 'mediatek,mt8135-pctl-a-syscfg', 'mediatek,mt8135-pctl-b-syscfg', 'mediatek,mt8365-syscfg', 'microchip,lan966x-cpu-syscon', 'microchip,sparx5-cpu-syscon', 'mstar,msc313-pmsleep', 'nuvoton,ma35d1-sys', 'nuvoton,wpcm450-shm', 'rockchip,px30-qos', 'rockchip,rk3036-qos', 'rockchip,rk3066-qos', 'rockchip,rk3128-qos', 'rockchip,rk3228-qos', 'rockchip,rk3288-qos', 'rockchip,rk3368-qos', 'rockchip,rk3399-qos', 'rockchip,rk3568-qos', 'rockchip,rk3588-qos', 'rockchip,rv1126-qos', 'starfive,jh7100-sysmain', 'ti,am62-usb-phy-ctrl', 'ti,am654-dss-oldi-io-ctrl', 'ti,am654-serdes-ctrl', 'ti,j784s4-pcie-ctrl']
from schema $id: http://devicetree.org/schemas/mfd/syscon.yaml#
^ permalink raw reply
* Re: [PATCH v3 0/3] arm64: qcom: sm8650: add support for the SM8650-HDK board
From: Rob Herring @ 2024-03-25 13:55 UTC (permalink / raw)
To: Neil Armstrong
Cc: Vladimir Zapolskiy, Krzysztof Kozlowski, Konrad Dybcio,
linux-arm-msm, Krzysztof Kozlowski, linux-kernel, Bjorn Andersson,
Conor Dooley, devicetree
In-Reply-To: <20240325-topic-sm8650-upstream-hdk-v3-0-4f365d7932af@linaro.org>
On Mon, 25 Mar 2024 11:26:36 +0100, Neil Armstrong wrote:
> The SM8650-HDK is an embedded development platforms for the
> Snapdragon 8 Gen 3 SoC aka SM8650, with the following features:
> - Qualcomm SM8650 SoC
> - 16GiB On-board LPDDR5
> - On-board WiFi 7 + Bluetooth 5.3/BLE
> - On-board UFS4.0
> - M.2 Key B+M Gen3x2 PCIe Slot
> - HDMI Output
> - USB-C Connector with DP Almode & Audio Accessory mode
> - Micro-SDCard Slot
> - Audio Jack with Playback and Microphone
> - 2 On-board Analog microphones
> - 2 On-board Speakers
> - 96Boards Compatible Low-Speed and High-Speed connectors [1]
> - For Camera, Sensors and external Display cards
> - Compatible with the Linaro Debug board [2]
> - SIM Slot for Modem
> - Debug connectors
> - 6x On-Board LEDs
>
> An optional Display Card kit can be connected on top,
> an overlay is handled to add support for the DSI Display
> and Touch Controller.
>
> Product Page: [3]
>
> Build Dependencies: None
>
> Functional Dependencies:
> - PCIe 1 PHY AUX Clock: https://lore.kernel.org/all/20240322-topic-sm8x50-upstream-pcie-1-phy-aux-clk-v2-0-3ec0a966d52f@linaro.org/
> - PCI-MSI Fix: https://lore.kernel.org/all/20240318-pci-bdf-sid-fix-v1-3-acca6c5d9cf1@linaro.org/
> - UCSI Fix: https://lore.kernel.org/all/20240315171836.343830-1-jthies@google.com/
> - USB IRQs DT check fix: https://lore.kernel.org/all/20240314-topic-sm8650-upstream-usb-dt-irq-fix-v1-1-ea8ab2051869@linaro.org/
>
> [1] https://www.96boards.org/specifications/
> [2] https://git.codelinaro.org/linaro/qcomlt/debugboard
> [3] https://www.lantronix.com/products/snapdragon-8-gen-3-mobile-hardware-development-kit/
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> Changes in v3:
> - fixed regulator node name to fix ordering
> - deleted pcie_1_phy_aux clock
> - removed undeeded mdss_mdp status okay
> - collected revied & tested tags
> - Link to v2: https://lore.kernel.org/r/20240318-topic-sm8650-upstream-hdk-v2-0-b63a5d45a784@linaro.org
>
> Changes in v2:
> - Fixed commit messages with links, and recently added product page URL
> - Swapped i2c3/i2c6 nodes
> - Moved pcie_1_phy_aux_clk under pcie1_phy
> - Removed duplicate mdp_vsync pinctrl state
> - Collected review & tested tags
> - Link to v1: https://lore.kernel.org/r/20240223-topic-sm8650-upstream-hdk-v1-0-ccca645cd901@linaro.org
>
> ---
> Neil Armstrong (3):
> dt-bindings: arm: qcom: Document the HDK8650 board
> arm64: dts: qcom: sm8650: add support for the SM8650-HDK board
> arch: arm64: dts: sm8650-hdk: add support for the Display Card overlay
>
> Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
> arch/arm64/boot/dts/qcom/Makefile | 5 +
> .../boot/dts/qcom/sm8650-hdk-display-card.dtso | 144 +++
> arch/arm64/boot/dts/qcom/sm8650-hdk.dts | 1251 ++++++++++++++++++++
> 4 files changed, 1401 insertions(+)
> ---
> base-commit: 0cd9d04a3ce7cd228d32adaf99a56708161a6b8a
> change-id: 20240223-topic-sm8650-upstream-hdk-e21cfd6f1de8
>
> Best regards,
> --
> Neil Armstrong <neil.armstrong@linaro.org>
>
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
New warnings running 'make CHECK_DTBS=y qcom/sm8650-hdk.dtb' for 20240325-topic-sm8650-upstream-hdk-v3-0-4f365d7932af@linaro.org:
arch/arm64/boot/dts/qcom/sm8650-hdk.dtb: pcie-1-phy-aux-clk: 'clock-frequency' is a required property
from schema $id: http://devicetree.org/schemas/clock/fixed-clock.yaml#
arch/arm64/boot/dts/qcom/sm8650-hdk.dtb: usb@a6f8800: interrupt-names:0: 'pwr_event' was expected
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
arch/arm64/boot/dts/qcom/sm8650-hdk.dtb: usb@a6f8800: interrupt-names:1: 'hs_phy_irq' was expected
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
arch/arm64/boot/dts/qcom/sm8650-hdk.dtb: usb@a6f8800: interrupt-names:2: 'dp_hs_phy_irq' was expected
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
arch/arm64/boot/dts/qcom/sm8650-hdk.dtb: usb@a6f8800: interrupt-names:3: 'dm_hs_phy_irq' was expected
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
arch/arm64/boot/dts/qcom/sm8650-hdk.dtb: usb@a6f8800: interrupt-names: ['hs_phy_irq', 'ss_phy_irq', 'dm_hs_phy_irq', 'dp_hs_phy_irq'] is too short
from schema $id: http://devicetree.org/schemas/usb/qcom,dwc3.yaml#
^ permalink raw reply
* Re: [PATCH v11 0/7] drm/meson: add support for MIPI DSI Display
From: Rob Herring @ 2024-03-25 13:55 UTC (permalink / raw)
To: Neil Armstrong
Cc: David Airlie, linux-amlogic, linux-kernel, Conor Dooley,
Stephen Boyd, Thomas Zimmermann, devicetree, Krzysztof Kozlowski,
dri-devel, Conor Dooley, Daniel Vetter, Michael Turquette,
Nicolas Belin, Lukas F. Hartmann, Maxime Ripard,
Maarten Lankhorst, Jerome Brunet, Kevin Hilman,
Martin Blumenstingl, Jagan Teki, linux-clk, linux-arm-kernel
In-Reply-To: <20240325-amlogic-v6-4-upstream-dsi-ccf-vim3-v11-0-04f55de44604@linaro.org>
On Mon, 25 Mar 2024 12:09:46 +0100, Neil Armstrong wrote:
> The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> glue on the same Amlogic SoCs.
>
> This is a follow-up of v5 now the DRM patches are applied, the clk & DT changes
> remains for a full DSI support on G12A & SM1 platforms.
>
> The DW-MIPI-DSI transceiver + D-PHY are clocked by the GP0 PLL, and the ENCL encoder + VIU
> pixel reader by the VCLK2 clock using the HDMI PLL.
>
> The DW-MIPI-DSI transceiver gets this pixel stream as input clocked with the VCLK2 clock.
>
> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> DW-MIPI-DSI transceiver.
>
> The clock setup has been redesigned to use CCF, a common PLL (GP0) and the VCLK2 clock
> path for DSI in preparation of full CCF support and possibly dual display with HDMI.
>
> The change from v5 is that now we use a "VCLK" driver instead of notifier and rely
> on CLK_SET_RATE_GATE to ensure the VCLK gate operation are called.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> Changes in v11:
> - Rebased on v6.9-rc1
> - Fixed overlay handling/creation
> - Link to v10: https://lore.kernel.org/r/20240205-amlogic-v6-4-upstream-dsi-ccf-vim3-v10-0-dc06073d5330@linaro.org
>
> Changes in v10:
> - Rename regmap_vclk to meson_clk and add _gate for the gate
> - Move COMMON_CLK_MESON_VCLK to following patch
> - Remove CLK_SET_RATE_PARENT from g12a_vclk2_sel, keep it only on mipi_dsi_pxclk_sel
> - Add more info on commit message to specify how clock setup is designed
> - Remove forgotten CLK_IGNORE_UNUSED on g12a_vclk2_input
> - Remove useless CLK_SET_RATE_PARENT on g12a_vclk2_div to stop propagatting rate _after_ vclk2_div
> - Remove invalid CLK_SET_RATE_GATE on g12a_vclk2 since it's not a divider...
> - Drop already applied patches
> - move Khadas TS050 changes as an overlay
> - Link to v9: https://lore.kernel.org/r/20231124-amlogic-v6-4-upstream-dsi-ccf-vim3-v9-0-95256ed139e6@linaro.org
>
> Changes in v9:
> - Colledte reviewed-bys
> - Fixed patches 2 & 4, commit messages and bindings format
> - Link to v8: https://lore.kernel.org/r/20231109-amlogic-v6-4-upstream-dsi-ccf-vim3-v8-0-81e4aeeda193@linaro.org
>
> Changes in v8:
> - Switch vclk clk driver to parm as requested by Jerome
> - Added bindings fixes to amlogic,meson-axg-mipi-pcie-analog & amlogic,g12a-mipi-dphy-analog
> - Fixed DT errors in vim3 example and MNT Reform DT
> - Rebased on next-20231107, successfully tested on VIM3L
> - Link to v7: https://lore.kernel.org/r/20230803-amlogic-v6-4-upstream-dsi-ccf-vim3-v7-0-762219fc5b28@linaro.org
>
> Changes in v7:
> - Added review tags
> - Fixed patch 5 thanks to George
> - Link to v6: https://lore.kernel.org/r/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v6-0-fd2ac9845472@linaro.org
>
> Changes in v6:
> - dropped applied DRM patches
> - dropped clk private prefix patches
> - rebased on top of 20230607-topic-amlogic-upstream-clkid-public-migration-v2-0-38172d17c27a@linaro.org
> - re-ordered/cleaned ENCL patches to match clkid public migration
> - Added new "vclk" driver
> - uses vclk driver instead of notifier
> - cleaned VCLK2 clk flags
> - add px_clk gating from DSI driver
> - Link to v5: https://lore.kernel.org/r/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v5-0-56eb7a4d5b8e@linaro.org
>
> Changes in v5:
> - Aded PRIV all the G12 internal clk IDS to simplify public exposing
> - Fixed the DSI bindings
> - Fixed the DSI HSYNC/VSYNC polarity handling
> - Fixed the DSI clock setup
> - Fixed the DSI phy timings
> - Dropped components for DSI, only keeping it for HDMI
> - Added MNT Reform 2 CM4 DT
> - Dropped already applied PHY fix
> - Link to v4: https://lore.kernel.org/r/20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-v4-0-2592c29ea263@linaro.org
>
> Changes from v3 at [3]:
> - switched all clk setup via CCF
> - using single PLL for DSI controller & ENCL encoder
> - added ENCL clocks to CCF
> - make the VCLK2 clocks configuration by CCF
> - fixed probe/bind of DSI controller to work with panels & bridges
> - added bit_clk to controller to it can setup the BIT clock aswell
> - added fix for components unbind
> - added fix for analog phy setup value
> - added TS050 timings fix
> - dropped previous clk control patch
>
> Changes from v2 at [2]:
> - Fixed patch 3
> - Added reviews from Jagan
> - Rebased on v5.19-rc1
>
> Changes from v1 at [1]:
> - fixed DSI host bindings
> - add reviewed-by tags for bindings
> - moved magic values to defines thanks to Martin's searches
> - added proper prefixes to defines
> - moved phy_configure to phy_init() dw-mipi-dsi callback
> - moved phy_on to a new phy_power_on() dw-mipi-dsi callback
> - correctly return phy_init/configure errors to callback returns
>
> [1] https://lore.kernel.org/r/20200907081825.1654-1-narmstrong@baylibre.com
> [2] https://lore.kernel.org/r/20220120083357.1541262-1-narmstrong@baylibre.com
> [3] https://lore.kernel.org/r/20220617072723.1742668-1-narmstrong@baylibre.com
>
> ---
> Neil Armstrong (7):
> dt-bindings: arm: amlogic: Document the MNT Reform 2 CM4 adapter with a BPI-CM4 Module
> clk: meson: add vclk driver
> clk: meson: g12a: make VCLK2 and ENCL clock path configurable by CCF
> drm/meson: gate px_clk when setting rate
> arm64: meson: g12-common: add the MIPI DSI nodes
> arm64: meson: khadas-vim3l: add TS050 DSI panel overlay
> arm64: dts: amlogic: meson-g12b-bananapi-cm4: add support for MNT Reform2 with CM4 adaper
>
> Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
> arch/arm64/boot/dts/amlogic/Makefile | 5 +
> arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 70 ++++
> .../meson-g12b-bananapi-cm4-mnt-reform2.dts | 384 +++++++++++++++++++++
> .../boot/dts/amlogic/meson-khadas-vim3-ts050.dtso | 108 ++++++
> drivers/clk/meson/Kconfig | 5 +
> drivers/clk/meson/Makefile | 1 +
> drivers/clk/meson/g12a.c | 72 ++--
> drivers/clk/meson/vclk.c | 141 ++++++++
> drivers/clk/meson/vclk.h | 51 +++
> drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 7 +
> 11 files changed, 825 insertions(+), 20 deletions(-)
> ---
> base-commit: 4cece764965020c22cff7665b18a012006359095
> change-id: 20230512-amlogic-v6-4-upstream-dsi-ccf-vim3-b8e5217e1f4a
>
> Best regards,
> --
> Neil Armstrong <neil.armstrong@linaro.org>
>
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
New warnings running 'make CHECK_DTBS=y amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb' for 20240325-amlogic-v6-4-upstream-dsi-ccf-vim3-v11-0-04f55de44604@linaro.org:
arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb: /soc/bus@ff600000/bus@42000/clock-controller@0: failed to match any schema with compatible: ['amlogic,g12a-audio-clkc']
arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb: /soc/bus@ff600000/bus@42000/audio-controller@744: failed to match any schema with compatible: ['amlogic,g12a-tohdmitx']
arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb: sys-ctrl@0: '#address-cells', '#size-cells', 'ranges' do not match any of the regexes: 'pinctrl-[0-9]+'
from schema $id: http://devicetree.org/schemas/soc/amlogic/amlogic,meson-gx-hhi-sysctrl.yaml#
arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb: sound: Unevaluated properties are not allowed ('assigned-clock-parents', 'assigned-clock-rates', 'assigned-clocks' were unexpected)
from schema $id: http://devicetree.org/schemas/sound/amlogic,axg-sound-card.yaml#
arch/arm64/boot/dts/amlogic/meson-g12b-bananapi-cm4-mnt-reform2.dtb: sound: 'anyOf' conditional failed, one must be fixed:
'clocks' is a required property
'#clock-cells' is a required property
from schema $id: http://devicetree.org/schemas/clock/clock.yaml#
^ permalink raw reply
* Re: [PATCH v7 00/15] media: Add driver for the Raspberry Pi <5 CSI-2 receiver
From: Rob Herring @ 2024-03-25 13:55 UTC (permalink / raw)
To: Laurent Pinchart
Cc: David Plowman, linux-media, Krzysztof Kozlowski, Ray Jui,
Jean-Michel Hautbois, Sakari Ailus, kernel-list, linux-rpi-kernel,
Conor Dooley, devicetree, Scott Branden, bcm-kernel-feedback-list,
Hans Verkuil, Rob Herring, Dave Stevenson, Florian Fainelli,
Naushir Patuck
In-Reply-To: <20240324220854.15010-1-laurent.pinchart@ideasonboard.com>
On Mon, 25 Mar 2024 00:08:36 +0200, Laurent Pinchart wrote:
> Hello everybody,
>
> This patch series adds a new driver for the BCM2835 (and derivative)
> CCP2/CSI2 camera interface named Unicam. This IP core is found in the
> VC4-based Raspberry Pi, namely the Pi Zero, Pi 3 and Pi 4.
>
> Camera support for Raspberry Pi 4 currently relies on a downstream
> Unicam driver that live in the Raspberry Pi kernel tree ([1]). The
> driver uses the V4L2 API, but works around the lack of features in V4L2
> to properly support sensor embedded data. Since the Unicam driver
> development by Raspberry Pi, some of those features have been merged in
> the kernel (namely the V4L2 streams API) or are being developed (namely
> generic metadata formats and subdev internal pads), with patches posted
> for review on the linux-media mailing list ([2]).
>
> This new upstream driver is based on the downstream code, extensively
> reworked to use the new V4L2 APIs.
>
> The series is based on top of a merge of
>
> - v8 of the generic metadata and internal pads, rebased on v6.9-rc1 ([3])
> - the downstream ISP driver ported to mainline ([4])
>
> For convenience, it can be found in [5]. Note that the ISP driver is
> getting upstreamed separately.
>
> The series starts with five patches that add support for streams and
> embedded data to the imx219 driver (01/15 to 05/15). Patches 06/15 to
> 09/15 then add the Unicam driver, with new V4L2 pixel formats (06/15 and
> 07/15) and DT bindings (08/15) The remaining patches cover DT
> integration (10/15 to 14/15) with a sample DT overlay for the IMX219
> camera module (15/15).
>
> The patches have been tested on a Raspberry Pi 4 using an IMX219 camera
> module (the Raspberry Pi camera v2), with libcamera. Updates are needed
> to libcamera to use the new V4L2 APIs, patches have been posted to [6].
> For manual testing with media-ctl, corresponding API updates to
> v4l-utils are available at [7].
>
> The changes to the imx219 driver effectively define the interface that
> raw sensors should expose to userspace. This needs to be documented
> explicitly. When posting v6, I stated that I would like the series to
> first get a review round, which will likely raise API questions. and
> then work on the documentation. As not many API questions have been
> raised yet, I'll give reviewers another chance :-)
>
> As a summary, more work is needed, in particular documenting how to use
> the API in raw camera sensor drivers, and implementing support for the
> latest generic metadata API in media-ctl and v4l2-compliance. I'm
> however happy with the unicam implementation, and I believe we're really
> nearing completion. This series, along with the libcamera support, help
> validating the new kernel APIs. We have in my opinion reached a point
> where we can start converting other sensor drivers from the downstream
> Raspberry Pi kernel to the standard APIs for embedded data, as well as
> integrating the APIs in the Raspberry Pi 5 CFE driver.
>
> [1] https://github.com/raspberrypi/linux/tree/rpi-6.1.y/drivers/media/platform/bcm2835
> [2] https://lore.kernel.org/linux-media/20240313072516.241106-1-sakari.ailus@linux.intel.com/
> [3] https://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux.git/log/?h=rpi/v6.9/metadata/v8
> [4] https://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux.git/log/?h=rpi/v6.9/isp/v2
> [5] https://git.kernel.org/pub/scm/linux/kernel/git/pinchartl/linux.git/log/?h=rpi/v6.9/unicam/next
> [6] https://lists.libcamera.org/pipermail/libcamera-devel/2024-March/040711.html
> [7] https://git.linuxtv.org/pinchartl/v4l-utils.git/log/?h=metadata
>
> Here's the mandatory v4l2-compliance report. There are 5 errors, which
> are caused by v4l2-compliance not supporting the new embedded data APIs
> yet. This will be fixed and patches for v4l2-compliance will be
> submitted (alongside patches to media-ctl).
>
> v4l2-compliance 1.27.0-5180, 64 bits, 64-bit time_t
> v4l2-compliance SHA: c14579f7e5f5 2024-03-01 20:29:24
>
> Compliance test for unicam device /dev/media0:
>
> Media Driver Info:
> Driver name : unicam
> Model : unicam
> Serial :
> Bus info : platform:fe801000.csi
> Media version : 6.8.0
> Hardware revision: 0x00000000 (0)
> Driver version : 6.8.0
>
> Required ioctls:
> test MEDIA_IOC_DEVICE_INFO: OK
> test invalid ioctls: OK
>
> Allow for multiple opens:
> test second /dev/media0 open: OK
> test MEDIA_IOC_DEVICE_INFO: OK
> test for unlimited opens: OK
>
> Media Controller ioctls:
> test MEDIA_IOC_G_TOPOLOGY: OK
> Entities: 4 Interfaces: 4 Pads: 8 Links: 7
> test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
> test MEDIA_IOC_SETUP_LINK: OK
>
> Total for unicam device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0
> --------------------------------------------------------------------------------
> Compliance test for unicam device /dev/video0:
>
> Driver Info:
> Driver name : unicam
> Card type : unicam
> Bus info : platform:fe801000.csi
> Driver version : 6.8.0
> Capabilities : 0xa4a00001
> Video Capture
> Metadata Capture
> I/O MC
> Streaming
> Extended Pix Format
> Device Capabilities
> Device Caps : 0x24200001
> Video Capture
> I/O MC
> Streaming
> Extended Pix Format
> Media Driver Info:
> Driver name : unicam
> Model : unicam
> Serial :
> Bus info : platform:fe801000.csi
> Media version : 6.8.0
> Hardware revision: 0x00000000 (0)
> Driver version : 6.8.0
> Interface Info:
> ID : 0x0300000d
> Type : V4L Video
> Entity Info:
> ID : 0x0000000b (11)
> Name : unicam-image
> Function : V4L2 I/O
> Flags : default
> Pad 0x0100000c : 0: Sink
> Link 0x0200000f: from remote pad 0x1000003 of entity 'unicam' (Video Interface Bridge): Data, Enabled, Immutable
>
> Required ioctls:
> test MC information (see 'Media Driver Info' above): OK
> test VIDIOC_QUERYCAP: OK
> test invalid ioctls: OK
>
> Allow for multiple opens:
> test second /dev/video0 open: OK
> test VIDIOC_QUERYCAP: OK
> test VIDIOC_G/S_PRIORITY: OK
> test for unlimited opens: OK
>
> Debug ioctls:
> test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> test VIDIOC_LOG_STATUS: OK
>
> Input ioctls:
> test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> test VIDIOC_ENUMAUDIO: OK (Not Supported)
> test VIDIOC_G/S/ENUMINPUT: OK
> test VIDIOC_G/S_AUDIO: OK (Not Supported)
> Inputs: 1 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
> test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Input/Output configuration ioctls:
> test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> test VIDIOC_G/S_EDID: OK (Not Supported)
>
> Control ioctls (Input 0):
> test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
> test VIDIOC_QUERYCTRL: OK (Not Supported)
> test VIDIOC_G/S_CTRL: OK (Not Supported)
> test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
> test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> Standard Controls: 0 Private Controls: 0
>
> Format ioctls (Input 0):
> test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> test VIDIOC_G/S_PARM: OK (Not Supported)
> test VIDIOC_G_FBUF: OK (Not Supported)
> test VIDIOC_G_FMT: OK
> test VIDIOC_TRY_FMT: OK
> test VIDIOC_S_FMT: OK
> test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> test Cropping: OK (Not Supported)
> test Composing: OK (Not Supported)
> test Scaling: OK
>
> Codec ioctls (Input 0):
> test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>
> Buffer ioctls (Input 0):
> test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> test CREATE_BUFS maximum buffers: OK
> test VIDIOC_EXPBUF: OK
> test Requests: OK (Not Supported)
>
> Total for unicam device /dev/video0: 47, Succeeded: 47, Failed: 0, Warnings: 0
> --------------------------------------------------------------------------------
> Compliance test for unicam device /dev/video1:
>
> Driver Info:
> Driver name : unicam
> Card type : unicam
> Bus info : platform:fe801000.csi
> Driver version : 6.8.0
> Capabilities : 0xa4a00001
> Video Capture
> Metadata Capture
> I/O MC
> Streaming
> Extended Pix Format
> Device Capabilities
> Device Caps : 0x24a00000
> Metadata Capture
> I/O MC
> Streaming
> Extended Pix Format
> Media Driver Info:
> Driver name : unicam
> Model : unicam
> Serial :
> Bus info : platform:fe801000.csi
> Media version : 6.8.0
> Hardware revision: 0x00000000 (0)
> Driver version : 6.8.0
> Interface Info:
> ID : 0x03000013
> Type : V4L Video
> Entity Info:
> ID : 0x00000011 (17)
> Name : unicam-embedded
> Function : V4L2 I/O
> Pad 0x01000012 : 0: Sink
> Link 0x02000015: from remote pad 0x1000004 of entity 'unicam' (Video Interface Bridge): Data, Enabled, Immutable
>
> Required ioctls:
> test MC information (see 'Media Driver Info' above): OK
> test VIDIOC_QUERYCAP: OK
> test invalid ioctls: OK
>
> Allow for multiple opens:
> test second /dev/video1 open: OK
> test VIDIOC_QUERYCAP: OK
> test VIDIOC_G/S_PRIORITY: OK
> test for unlimited opens: OK
>
> Debug ioctls:
> test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> test VIDIOC_LOG_STATUS: OK
>
> Input ioctls:
> test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> test VIDIOC_ENUMAUDIO: OK (Not Supported)
> test VIDIOC_G/S/ENUMINPUT: OK
> test VIDIOC_G/S_AUDIO: OK (Not Supported)
> Inputs: 1 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
> test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Input/Output configuration ioctls:
> test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> test VIDIOC_G/S_EDID: OK (Not Supported)
>
> Control ioctls (Input 0):
> test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
> test VIDIOC_QUERYCTRL: OK (Not Supported)
> test VIDIOC_G/S_CTRL: OK (Not Supported)
> test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
> test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> Standard Controls: 0 Private Controls: 0
>
> Format ioctls (Input 0):
> test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> test VIDIOC_G/S_PARM: OK (Not Supported)
> test VIDIOC_G_FBUF: OK (Not Supported)
> test VIDIOC_G_FMT: OK
> fail: v4l2-test-formats.cpp(590): dataformat 00003ff8 (x?) for buftype 13 not reported by ENUM_FMT
> test VIDIOC_TRY_FMT: FAIL
> test VIDIOC_S_FMT: OK
> test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> test Cropping: OK (Not Supported)
> test Composing: OK (Not Supported)
> test Scaling: OK (Not Supported)
>
> Codec ioctls (Input 0):
> test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>
> Buffer ioctls (Input 0):
> test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> test CREATE_BUFS maximum buffers: OK
> test VIDIOC_EXPBUF: OK
> test Requests: OK (Not Supported)
>
> Total for unicam device /dev/video1: 47, Succeeded: 46, Failed: 1, Warnings: 0
> --------------------------------------------------------------------------------
> Compliance test for unicam device /dev/v4l-subdev0:
>
> Driver Info:
> Driver version : 6.8.0
> Capabilities : 0x00000002
> Streams Support
> Client Capabilities: 0x0000000000000003
> streams interval-uses-which Media Driver Info:
> Driver name : unicam
> Model : unicam
> Serial :
> Bus info : platform:fe801000.csi
> Media version : 6.8.0
> Hardware revision: 0x00000000 (0)
> Driver version : 6.8.0
> Interface Info:
> ID : 0x03000017
> Type : V4L Sub-Device
> Entity Info:
> ID : 0x00000001 (1)
> Name : unicam
> Function : Video Interface Bridge
> Pad 0x01000002 : 0: Sink
> Link 0x02000009: from remote pad 0x1000006 of entity 'imx219 5-0010' (Camera Sensor): Data, Enabled, Immutable
> Pad 0x01000003 : 1: Source
> Link 0x0200000f: to remote pad 0x100000c of entity 'unicam-image' (V4L2 I/O): Data, Enabled, Immutable
> Pad 0x01000004 : 2: Source
> Link 0x02000015: to remote pad 0x1000012 of entity 'unicam-embedded' (V4L2 I/O): Data, Enabled, Immutable
>
> Required ioctls:
> test MC information (see 'Media Driver Info' above): OK
> test VIDIOC_SUDBEV_QUERYCAP: OK
> test invalid ioctls: OK
>
> Allow for multiple opens:
> test second /dev/v4l-subdev0 open: OK
> test VIDIOC_SUBDEV_QUERYCAP: OK
> test for unlimited opens: OK
>
> Debug ioctls:
> test VIDIOC_LOG_STATUS: OK (Not Supported)
>
> Input ioctls:
> test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> test VIDIOC_ENUMAUDIO: OK (Not Supported)
> test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDIO: OK (Not Supported)
> Inputs: 0 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
> test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> Outputs: 0 Audio Outputs: 0 Modulators: 0
>
> Input/Output configuration ioctls:
> test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> test VIDIOC_G/S_EDID: OK (Not Supported)
>
> Sub-Device routing ioctls:
> fail: v4l2-test-subdevs.cpp(631): !(source->flags & MEDIA_PAD_FL_SOURCE)
> test Try VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: FAIL
> fail: v4l2-test-subdevs.cpp(631): !(source->flags & MEDIA_PAD_FL_SOURCE)
> test Active VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: FAIL
>
> Sub-Device ioctls (Sink Pad 0):
>
> Sub-Device ioctls (Source Pad 1):
>
> Sub-Device ioctls (Source Pad 2):
>
> Control ioctls:
> test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
> test VIDIOC_QUERYCTRL: OK (Not Supported)
> test VIDIOC_G/S_CTRL: OK (Not Supported)
> test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
> test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> Standard Controls: 0 Private Controls: 0
>
> Format ioctls:
> test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
> test VIDIOC_G/S_PARM: OK (Not Supported)
> test VIDIOC_G_FBUF: OK (Not Supported)
> test VIDIOC_G_FMT: OK (Not Supported)
> test VIDIOC_TRY_FMT: OK (Not Supported)
> test VIDIOC_S_FMT: OK (Not Supported)
> test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> test Cropping: OK (Not Supported)
> test Composing: OK (Not Supported)
> test Scaling: OK (Not Supported)
>
> Codec ioctls:
> test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>
> Buffer ioctls:
> test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
> test CREATE_BUFS maximum buffers: OK
> test VIDIOC_EXPBUF: OK (Not Supported)
> test Requests: OK (Not Supported)
>
> Total for unicam device /dev/v4l-subdev0: 47, Succeeded: 45, Failed: 2, Warnings: 0
> --------------------------------------------------------------------------------
> Compliance test for unicam device /dev/v4l-subdev1:
>
> Driver Info:
> Driver version : 6.8.0
> Capabilities : 0x00000002
> Streams Support
> Client Capabilities: 0x0000000000000003
> streams interval-uses-which Media Driver Info:
> Driver name : unicam
> Model : unicam
> Serial :
> Bus info : platform:fe801000.csi
> Media version : 6.8.0
> Hardware revision: 0x00000000 (0)
> Driver version : 6.8.0
> Interface Info:
> ID : 0x03000019
> Type : V4L Sub-Device
> Entity Info:
> ID : 0x00000005 (5)
> Name : imx219 5-0010
> Function : Camera Sensor
> Pad 0x01000006 : 0: Source
> Link 0x02000009: to remote pad 0x1000002 of entity 'unicam' (Video Interface Bridge): Data, Enabled, Immutable
> Pad 0x01000007 : 1: Sink, 00000008
> Pad 0x01000008 : 2: Sink, 00000008
>
> Required ioctls:
> test MC information (see 'Media Driver Info' above): OK
> test VIDIOC_SUDBEV_QUERYCAP: OK
> test invalid ioctls: OK
>
> Allow for multiple opens:
> test second /dev/v4l-subdev1 open: OK
> test VIDIOC_SUBDEV_QUERYCAP: OK
> test for unlimited opens: OK
>
> Debug ioctls:
> test VIDIOC_LOG_STATUS: OK (Not Supported)
>
> Input ioctls:
> test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> test VIDIOC_ENUMAUDIO: OK (Not Supported)
> test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> test VIDIOC_G/S_AUDIO: OK (Not Supported)
> Inputs: 0 Audio Inputs: 0 Tuners: 0
>
> Output ioctls:
> test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>
> Dave Stevenson (2):
> dt-bindings: media: Add bindings for bcm2835-unicam
> media: bcm2835-unicam: Add support for CCP2/CSI2 camera interface
>
> Jean-Michel Hautbois (3):
> media: v4l: Add V4L2-PIX-FMT-Y12P format
> media: v4l: Add V4L2-PIX-FMT-Y14P format
> ARM: dts: bcm2835: Add Unicam CSI nodes
>
> Laurent Pinchart (8):
> media: i2c: imx219: Inline imx219_update_pad_format() in its caller
> media: i2c: imx219: Add internal image sink pad
> media: i2c: imx219: Report internal routes to userspace
> media: i2c: imx219: Report streams using frame descriptors
> media: i2c: imx219: Add embedded data support
> ARM: dts: bcm2835-rpi: Move firmware-clocks from bcm2711 to bcm2835
> ARM: dts: bcm2711-rpi-4-b: Add CAM1 regulator
> [DNI] arm64: dts: broadcom: Add overlay for Raspberry Pi 4B IMX219
> camera
>
> Uwe Kleine-König (2):
> ARM: dts: bcm2711-rpi: Add pinctrl-based multiplexing for I2C0
> ARM: dts: bcm2711-rpi-cm4-io: Add RTC on I2C0
>
> .../bindings/media/brcm,bcm2835-unicam.yaml | 117 +
> .../media/v4l/pixfmt-yuv-luma.rst | 48 +
> MAINTAINERS | 7 +
> .../arm/boot/dts/broadcom/bcm2711-rpi-4-b.dts | 7 +
> .../boot/dts/broadcom/bcm2711-rpi-cm4-io.dts | 9 +
> arch/arm/boot/dts/broadcom/bcm2711-rpi.dtsi | 34 +-
> arch/arm/boot/dts/broadcom/bcm2711.dtsi | 8 +
> arch/arm/boot/dts/broadcom/bcm2835-rpi.dtsi | 19 +
> arch/arm/boot/dts/broadcom/bcm283x.dtsi | 24 +
> arch/arm64/boot/dts/broadcom/Makefile | 2 +
> .../dts/broadcom/bcm2711-rpi-4-b-imx219.dtso | 65 +
> drivers/media/i2c/imx219.c | 420 ++-
> drivers/media/platform/Kconfig | 1 +
> drivers/media/platform/Makefile | 1 +
> drivers/media/platform/broadcom/Kconfig | 23 +
> drivers/media/platform/broadcom/Makefile | 3 +
> .../platform/broadcom/bcm2835-unicam-regs.h | 255 ++
> .../media/platform/broadcom/bcm2835-unicam.c | 2667 +++++++++++++++++
> drivers/media/v4l2-core/v4l2-ioctl.c | 2 +
> include/uapi/linux/videodev2.h | 2 +
> 20 files changed, 3639 insertions(+), 75 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> create mode 100644 arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b-imx219.dtso
> create mode 100644 drivers/media/platform/broadcom/Kconfig
> create mode 100644 drivers/media/platform/broadcom/Makefile
> create mode 100644 drivers/media/platform/broadcom/bcm2835-unicam-regs.h
> create mode 100644 drivers/media/platform/broadcom/bcm2835-unicam.c
>
>
> base-commit: e21180b6d61e9b4ee15e2047b55b14b306465d15
> --
> Regards,
>
> Laurent Pinchart
>
>
My bot found new DTB warnings on the .dts files added or changed in this
series.
Some warnings may be from an existing SoC .dtsi. Or perhaps the warnings
are fixed by another series. Ultimately, it is up to the platform
maintainer whether these warnings are acceptable or not. No need to reply
unless the platform maintainer has comments.
If you already ran DT checks and didn't see these error(s), then
make sure dt-schema is up to date:
pip3 install dtschema --upgrade
New warnings running 'make CHECK_DTBS=y broadcom/bcm2711-rpi-4-b.dtb broadcom/bcm2711-rpi-cm4-io.dtb' for 20240324220854.15010-1-laurent.pinchart@ideasonboard.com:
arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dtb: soc: firmware: {'compatible': ['raspberrypi,bcm2835-firmware', 'simple-mfd'], '#address-cells': [[1]], '#size-cells': [[1]], 'mboxes': [[29]], 'dma-ranges': True, 'phandle': [[30]], 'clocks': {'compatible': ['raspberrypi,firmware-clocks'], '#clock-cells': [[1]], 'phandle': [[16]]}, 'gpio': {'compatible': ['raspberrypi,firmware-gpio'], 'gpio-controller': True, '#gpio-cells': [[2]], 'status': ['okay'], 'gpio-line-names': ['BT_ON', 'WL_ON', 'PWR_LED_OFF', 'GLOBAL_RESET', 'VDD_SD_IO_SEL', 'CAM_GPIO', 'SD_PWR_ON', ''], 'phandle': [[10]]}, 'reset': {'compatible': ['raspberrypi,firmware-reset'], '#reset-cells': [[1]], 'phandle': [[39]]}} should not be valid under {'type': 'object'}
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dtb: soc: power: {'compatible': ['raspberrypi,bcm2835-power'], 'firmware': [[30]], '#power-domain-cells': [[1]], 'phandle': [[11]]} should not be valid under {'type': 'object'}
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dtb: soc: firmware: {'compatible': ['raspberrypi,bcm2835-firmware', 'simple-mfd'], '#address-cells': [[1]], '#size-cells': [[1]], 'mboxes': [[27]], 'dma-ranges': True, 'phandle': [[28]], 'clocks': {'compatible': ['raspberrypi,firmware-clocks'], '#clock-cells': [[1]], 'phandle': [[16]]}, 'gpio': {'compatible': ['raspberrypi,firmware-gpio'], 'gpio-controller': True, '#gpio-cells': [[2]], 'status': ['okay'], 'gpio-line-names': ['BT_ON', 'WL_ON', 'PWR_LED_OFF', 'ANT1', 'VDD_SD_IO_SEL', 'CAM_GPIO', 'SD_PWR_ON', 'ANT2'], 'phandle': [[10]], 'ant1-hog': {'gpio-hog': True, 'gpios': [[3, 0]], 'output-high': True, 'line-name': ['ant1'], 'phandle': [[164]]}, 'ant2-hog': {'gpio-hog': True, 'gpios': [[7, 0]], 'output-low': True, 'line-name': ['ant2'], 'phandle': [[165]]}}, 'reset': {'compatible': ['raspberrypi,firmware-reset'], '#reset-cells': [[1]], 'phandle': [[166]]}} should not be valid under {'type': 'object'}
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dtb: soc: power: {'compatible': ['raspberrypi,bcm2835-power'], 'firmware': [[28]], '#power-domain-cells': [[1]], 'phandle': [[11]]} should not be valid under {'type': 'object'}
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dtb: i2c0mux: $nodename:0: 'i2c0mux' does not match '^(i2c-?)?mux'
from schema $id: http://devicetree.org/schemas/i2c/i2c-mux-pinctrl.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-4-b.dtb: i2c0mux: Unevaluated properties are not allowed ('#address-cells', '#size-cells', 'i2c@0', 'i2c@1' were unexpected)
from schema $id: http://devicetree.org/schemas/i2c/i2c-mux-pinctrl.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dtb: i2c0mux: $nodename:0: 'i2c0mux' does not match '^(i2c-?)?mux'
from schema $id: http://devicetree.org/schemas/i2c/i2c-mux-pinctrl.yaml#
arch/arm/boot/dts/broadcom/bcm2711-rpi-cm4-io.dtb: i2c0mux: Unevaluated properties are not allowed ('#address-cells', '#size-cells', 'i2c@0', 'i2c@1' were unexpected)
from schema $id: http://devicetree.org/schemas/i2c/i2c-mux-pinctrl.yaml#
^ permalink raw reply
* [PATCH 5/5] arm64: dts: rockchip: Add GameForce Chi
From: Chris Morgan @ 2024-03-25 13:49 UTC (permalink / raw)
To: linux-rockchip
Cc: dri-devel, devicetree, daniel, airlied, sam, quic_jesszhan,
neil.armstrong, megi, kernel, agx, heiko, conor+dt,
krzysztof.kozlowski+dt, robh, Chris Morgan
In-Reply-To: <20240325134959.11807-1-macroalpha82@gmail.com>
From: Chris Morgan <macromorgan@hotmail.com>
Add support for the GameForce Chi, which is a handheld gaming console
from GameForce with a Rockchip RK3326 SoC. The device has a 640x480
3.5" dual-lane DSI display, one analog joystick connected to the SoC
SARADC controller and a second analog joystick connected to an unknown
UART based ADC, a single SD card slot, a single USB-C port for
charging, and onboard RTL8723BS WiFi/Bluetooth combo, multiple face
buttons, and an array of R/G/B LEDs used for key backlighting.
The vendor was unable to provide details on the unknown UART based
ADC which I have documented via a comment in the device-tree, and
the vendor also does not have available Bluetooth firmware (the BT
was not previously working on the vendor's OS, this has also been
noted in a device-tree comment).
Aside from the right analog ADC joystick and bluetooth all hardware has
been tested and is working as expected.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
arch/arm64/boot/dts/rockchip/Makefile | 1 +
.../dts/rockchip/rk3326-gameforce-chi.dts | 811 ++++++++++++++++++
2 files changed, 812 insertions(+)
create mode 100644 arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index f906a868b71a..584ee35da180 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351m.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351v.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-gameforce-chi.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2-v11.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go3.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts b/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
new file mode 100644
index 000000000000..f7a9e763fba0
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
@@ -0,0 +1,811 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Chris Morgan <macromorgan@hotmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3326.dtsi"
+
+/ {
+ model = "GameForce Chi";
+
+ compatible = "gameforce,chi", "rockchip,rk3326";
+
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdmmc;
+ mmc1 = &sdio;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ adc_joystick: adc-joystick {
+ compatible = "adc-joystick";
+ io-channels = <&saradc 0>,
+ <&saradc 1>;
+ poll-interval = <100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ axis@0 {
+ reg = <0>;
+ abs-flat = <10>;
+ abs-fuzz = <10>;
+ abs-range = <850 175>;
+ linux,code = <ABS_Y>;
+ };
+
+ axis@1 {
+ reg = <1>;
+ abs-flat = <10>;
+ abs-fuzz = <10>;
+ abs-range = <800 190>;
+ linux,code = <ABS_X>;
+ };
+ };
+
+ adc_keys: adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 2>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <60>;
+
+ button-1 {
+ label = "HAPPY1";
+ linux,code = <BTN_TRIGGER_HAPPY1>;
+ press-threshold-microvolt = <15000>;
+ };
+
+ button-2 {
+ label = "HAPPY2";
+ linux,code = <BTN_TRIGGER_HAPPY2>;
+ press-threshold-microvolt = <300000>;
+ };
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ power-supply = <&vcc_bl>;
+ pwms = <&pwm1 0 25000 0>;
+ };
+
+ battery: battery {
+ compatible = "simple-battery";
+ charge-full-design-microamp-hours = <3000000>;
+ charge-term-current-microamp = <300000>;
+ constant-charge-current-max-microamp = <1500000>;
+ constant-charge-voltage-max-microvolt = <4200000>;
+ factory-internal-resistance-micro-ohms = <180000>;
+ voltage-max-design-microvolt = <4250000>;
+ voltage-min-design-microvolt = <3400000>;
+
+ ocv-capacity-celsius = <20>;
+ ocv-capacity-table-0 = <4106000 100>, <4071000 95>, <4018000 90>, <3975000 85>,
+ <3946000 80>, <3908000 75>, <3877000 70>, <3853000 65>,
+ <3834000 60>, <3816000 55>, <3802000 50>, <3788000 45>,
+ <3774000 40>, <3760000 35>, <3748000 30>, <3735000 25>,
+ <3718000 20>, <3697000 15>, <3685000 10>, <3625000 5>,
+ <3400000 0>;
+ };
+
+ gpio_leds: gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ red_led: led-0 {
+ color = <LED_COLOR_ID_RED>;
+ gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+ };
+
+ green_led: led-1 {
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+ };
+
+ blue_led: led-2 {
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
+ };
+
+ white_led: led-3 {
+ color = <LED_COLOR_ID_WHITE>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ };
+
+ chg_led: led-4 {
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_CHARGING;
+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_HIGH>;
+ };
+
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&btn_pins_ctrl>;
+ pinctrl-names = "default";
+
+ button-a {
+ gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>;
+ label = "EAST";
+ linux,code = <BTN_EAST>;
+ };
+
+ button-b {
+ gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;
+ label = "SOUTH";
+ linux,code = <BTN_SOUTH>;
+ };
+
+ button-down {
+ gpios = <&gpio1 RK_PB5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-DOWN";
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ button-home {
+ gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>;
+ label = "HOME";
+ linux,code = <BTN_MODE>;
+ };
+
+ button-l1 {
+ gpios = <&gpio2 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "TL";
+ linux,code = <BTN_TL>;
+ };
+
+ button-l2 {
+ gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;
+ label = "TL2";
+ linux,code = <BTN_TL2>;
+ };
+
+ button-left {
+ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-r1 {
+ gpios = <&gpio2 RK_PA7 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR>;
+ };
+
+ button-r2 {
+ gpios = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR2>;
+ };
+
+ button-right {
+ gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-select {
+ gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;
+ label = "SELECT";
+ linux,code = <BTN_SELECT>;
+ };
+
+ button-start {
+ gpios = <&gpio2 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "START";
+ linux,code = <BTN_START>;
+ };
+
+ button-up {
+ gpios = <&gpio1 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "DPAD-UP";
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ button-x {
+ gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "NORTH";
+ linux,code = <BTN_NORTH>;
+ };
+
+ button-y {
+ gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+ label = "WEST";
+ linux,code = <BTN_WEST>;
+ };
+ };
+
+ multi-led {
+ compatible = "leds-group-multicolor";
+ color = <LED_COLOR_ID_RGB>;
+ function = LED_FUNCTION_KBD_BACKLIGHT;
+ leds = <&red_led>, <&green_led>, <&blue_led>;
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-0 = <&hp_det>;
+ pinctrl-names = "default";
+ simple-audio-card,name = "rk817_ext";
+ simple-audio-card,aux-devs = <&spk_amp>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,hp-det-gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Headphone", "Headphones",
+ "Speaker", "Internal Speakers";
+ simple-audio-card,routing =
+ "MICL", "Mic Jack",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "Internal Speakers", "Speaker Amp OUTL",
+ "Internal Speakers", "Speaker Amp OUTR",
+ "Speaker Amp INL", "HPOL",
+ "Speaker Amp INR", "HPOR";
+ simple-audio-card,pin-switches = "Internal Speakers";
+
+ simple-audio-card,codec {
+ sound-dai = <&rk817>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_2ch>;
+ };
+ };
+
+ spk_amp: audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&spk_amp_enable_h>;
+ pinctrl-names = "default";
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&wifi_enable_h>;
+ pinctrl-names = "default";
+ post-power-on-delay-ms = <200>;
+ reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
+ };
+
+ vccsys: vccsys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v8_sys";
+ regulator-always-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ };
+
+ vibrator_left: pwm-vibrator-l {
+ compatible = "pwm-vibrator";
+ pwm-names = "enable";
+ pwms = <&pwm4 0 25000 0>;
+ };
+
+ vibrator_right: pwm-vibrator-r {
+ compatible = "pwm-vibrator";
+ pwm-names = "enable";
+ pwms = <&pwm5 0 25000 0>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+ status = "okay";
+};
+
+&dsi {
+ status = "okay";
+
+ ports {
+ mipi_out: port@1 {
+ reg = <1>;
+
+ mipi_out_panel: endpoint {
+ remote-endpoint = <&mipi_in_panel>;
+ };
+ };
+ };
+
+ internal_display: panel@0 {
+ reg = <0>;
+ compatible = "gameforce,chi-panel";
+ backlight = <&backlight>;
+ iovcc-supply = <&vcc_lcd>;
+ vcc-supply = <&vcc_lcd>;
+ reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_LOW>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+};
+
+&dsi_dphy {
+ status = "okay";
+};
+
+&gpu {
+ mali-supply = <&vdd_logic>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ i2c-scl-falling-time-ns = <16>;
+ i2c-scl-rising-time-ns = <280>;
+ status = "okay";
+
+ rk817: pmic@20 {
+ compatible = "rockchip,rk817";
+ reg = <0x20>;
+ #clock-cells = <1>;
+ clock-names = "mclk";
+ clock-output-names = "rk808-clkout1", "xin32k";
+ clocks = <&cru SCLK_I2S1_OUT>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PC1 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&pmic_int>, <&i2s1_2ch_mclk>;
+ pinctrl-names = "default";
+ #sound-dai-cells = <0>;
+ system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vccsys>;
+ vcc2-supply = <&vccsys>;
+ vcc3-supply = <&vccsys>;
+ vcc4-supply = <&vccsys>;
+ vcc5-supply = <&vccsys>;
+ vcc6-supply = <&vccsys>;
+ vcc7-supply = <&vcc_3v0>;
+ vcc8-supply = <&vccsys>;
+ vcc9-supply = <&dcdc_boost>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1150000>;
+ regulator-min-microvolt = <950000>;
+ regulator-name = "vdd_logic";
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <950000>;
+ };
+ };
+
+ vdd_arm: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1350000>;
+ regulator-min-microvolt = <950000>;
+ regulator-name = "vdd_arm";
+ regulator-ramp-delay = <6001>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <950000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vcc_ddr";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_3v0: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc_3v0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+
+ vcc_1v8: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1800000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "vcc_1v8";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_1v0: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1000000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-name = "vdd_1v0";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_3v0_pmu: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "vcc_3v0_pmu";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <1800000>;
+ regulator-name = "vccio_sd";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_sd: LDO_REG6 {
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_sd";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_bl: LDO_REG7 {
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_bl";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_lcd: LDO_REG8 {
+ regulator-max-microvolt = <2800000>;
+ regulator-min-microvolt = <2800000>;
+ regulator-name = "vcc_lcd";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <2800000>;
+ };
+ };
+
+ vcc_wifi: LDO_REG9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <3300000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-name = "vcc_wifi";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ dcdc_boost: BOOST {
+ regulator-max-microvolt = <5000000>;
+ regulator-min-microvolt = <5000000>;
+ regulator-name = "dcdc_boost";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ otg_switch: OTG_SWITCH {
+ regulator-name = "otg_switch";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+
+ rk817_charger: charger {
+ monitored-battery = <&battery>;
+ rockchip,resistor-sense-micro-ohms = <10000>;
+ rockchip,sleep-enter-current-microamp = <300000>;
+ rockchip,sleep-filter-current-microamp = <100000>;
+ };
+ };
+};
+
+&i2s1_2ch {
+ status = "okay";
+};
+
+&io_domains {
+ vccio1-supply = <&vcc_3v0_pmu>;
+ vccio2-supply = <&vccio_sd>;
+ vccio3-supply = <&vcc_3v0>;
+ vccio4-supply = <&vcc_3v0>;
+ vccio5-supply = <&vcc_3v0>;
+ vccio6-supply = <&vcc_3v0>;
+ status = "okay";
+};
+
+&pinctrl {
+ bluetooth-pins {
+ bt_reset: bt-reset {
+ rockchip,pins =
+ <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ bt_wake_dev: bt-wake-dev {
+ rockchip,pins =
+ <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_wake_host: bt-wake-host {
+ rockchip,pins =
+ <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ headphone {
+ hp_det: hp-det {
+ rockchip,pins =
+ <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ gpio-btns {
+ btn_pins_ctrl: btn-pins-ctrl {
+ rockchip,pins =
+ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>,
+ <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
+ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>,
+ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ gpio-leds {
+ led_pins: led-pins {
+ rockchip,pins =
+ <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>,
+ <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins =
+ <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ soc_slppin_gpio: soc_slppin_gpio {
+ rockchip,pins =
+ <0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+
+ soc_slppin_rst: soc_slppin_rst {
+ rockchip,pins =
+ <0 RK_PA4 2 &pcfg_pull_none>;
+ };
+
+ soc_slppin_slp: soc_slppin_slp {
+ rockchip,pins =
+ <0 RK_PA4 1 &pcfg_pull_none>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins =
+ <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ speaker {
+ spk_amp_enable_h: spk-amp-enable-h {
+ rockchip,pins =
+ <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio1-supply = <&vcc_1v8>;
+ pmuio2-supply = <&vcc_3v0_pmu>;
+ status = "okay";
+};
+
+&pwm1 {
+ status = "okay";
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&pwm5 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdio {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ disable-wp;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-mmc;
+ no-sd;
+ non-removable;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&sdmmc {
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ no-sdio;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sfc {
+ #address-cells = <1>;
+ pinctrl-0 = <&sfc_clk &sfc_cs0 &sfc_bus2>;
+ pinctrl-names = "default";
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <108000000>;
+ spi-rx-bus-width = <2>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy {
+ status = "okay";
+
+ u2phy_otg: otg-port {
+ status = "okay";
+ };
+};
+
+&usb20_otg {
+ status = "okay";
+};
+
+/*
+ * The right ADC joystick exists connected to an unknown ADC
+ * controller which can be communicated with via uart0. This ADC device
+ * is an 8-pin SOIC with no markings located right next to the left ADC
+ * joystick ribbon cable. The pinout for this ADC controller appears to
+ * be pin 1 - VCC (2.8v), pin 2 - 1.8v (clk maybe?), pin 3 - GPIO 10,
+ * pin 4 - unknown, pin 5 - unknown, pin 6 - analog in, pin 7 - analog in,
+ * pin 8 - ground. There is currently a userspace UART driver for this
+ * device but it only works with the BSP joystick driver.
+ */
+&uart0 {
+ status = "okay";
+};
+
+/* Bluetooth was not working on BSP and is not currently working on
+ * mainline due to missing firmware. Bluetooth requires removal of DMA
+ * or else it will not probe.
+ */
+&uart1 {
+ /delete-property/ dma-names;
+ /delete-property/ dmas;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth: bluetooth {
+ compatible = "realtek,rtl8723ds-bt";
+ device-wake-gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
+ enable-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&bt_reset>, <&bt_wake_dev>, <&bt_wake_host>;
+ pinctrl-names = "default";
+ };
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m1_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&vopb {
+ status = "okay";
+};
+
+&vopb_mmu {
+ status = "okay";
+};
--
2.34.1
^ permalink raw reply related
* [PATCH 4/5] dt-bindings: arm: rockchip: Add GameForce Chi
From: Chris Morgan @ 2024-03-25 13:49 UTC (permalink / raw)
To: linux-rockchip
Cc: dri-devel, devicetree, daniel, airlied, sam, quic_jesszhan,
neil.armstrong, megi, kernel, agx, heiko, conor+dt,
krzysztof.kozlowski+dt, robh, Chris Morgan
In-Reply-To: <20240325134959.11807-1-macroalpha82@gmail.com>
From: Chris Morgan <macromorgan@hotmail.com>
The GameForce Chi is a handheld gaming device from GameForce powered
by the Rockchip RK3326 SoC.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index fcf7316ecd74..a5498974ceb4 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -236,6 +236,11 @@ properties:
- const: friendlyarm,nanopc-t6
- const: rockchip,rk3588
+ - description: GameForce Chi
+ items:
+ - const: gameforce,chi
+ - const: rockchip,rk3326
+
- description: GeekBuying GeekBox
items:
- const: geekbuying,geekbox
--
2.34.1
^ permalink raw reply related
* [PATCH 3/5] drm/panel: st7703: Add GameForce Chi Panel Support
From: Chris Morgan @ 2024-03-25 13:49 UTC (permalink / raw)
To: linux-rockchip
Cc: dri-devel, devicetree, daniel, airlied, sam, quic_jesszhan,
neil.armstrong, megi, kernel, agx, heiko, conor+dt,
krzysztof.kozlowski+dt, robh, Chris Morgan
In-Reply-To: <20240325134959.11807-1-macroalpha82@gmail.com>
From: Chris Morgan <macromorgan@hotmail.com>
The GameForce Chi is a handheld device with a 3.5" 640x480 ST7703 based
display panel.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
drivers/gpu/drm/panel/panel-sitronix-st7703.c | 87 +++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index a3e142f156d5..7d8302cca091 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -612,6 +612,92 @@ static const struct st7703_panel_desc rgb10max3_panel_desc = {
.init_sequence = rgb10max3_panel_init_sequence,
};
+static int gameforcechi_init_sequence(struct st7703 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /*
+ * Init sequence was supplied by the panel vendor. Panel will not
+ * respond to commands until it is brought out of sleep mode first.
+ */
+
+ mipi_dsi_dcs_exit_sleep_mode(dsi);
+ msleep(250);
+
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x31, 0x81, 0x05, 0xf9,
+ 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x44, 0x25, 0x00, 0x91, 0x0a, 0x00,
+ 0x00, 0x02, 0x4f, 0xd1, 0x00, 0x00, 0x37);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x0c, 0x10, 0x0a,
+ 0x50, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50,
+ 0x00, 0x00, 0x08, 0x70, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x46);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x00, 0x13, 0xf0);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b,
+ 0x03, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xc0, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x53, 0x00, 0x1e,
+ 0x1e, 0x77, 0xe1, 0xcc, 0xdd, 0x67, 0x77, 0x33,
+ 0x33);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x10, 0x10);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x6c, 0x7c);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0x08, 0x00, 0x0e, 0x00,
+ 0x00, 0xb0, 0xb1, 0x11, 0x31, 0x23, 0x28, 0x10,
+ 0xb0, 0xb1, 0x27, 0x08, 0x00, 0x04, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
+ 0x88, 0x88, 0xba, 0x60, 0x24, 0x08, 0x88, 0x88,
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0xba, 0x71, 0x35,
+ 0x18, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x97, 0x0a, 0x82, 0x02,
+ 0x13, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x88, 0xba, 0x17, 0x53, 0x88, 0x88, 0x88,
+ 0x88, 0x88, 0x88, 0x81, 0x88, 0xba, 0x06, 0x42,
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x10,
+ 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00);
+ mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x07, 0x0b,
+ 0x27, 0x2d, 0x3f, 0x3b, 0x37, 0x05, 0x0a, 0x0b,
+ 0x0f, 0x11, 0x0f, 0x12, 0x12, 0x18, 0x00, 0x07,
+ 0x0b, 0x27, 0x2d, 0x3f, 0x3b, 0x37, 0x05, 0xa0,
+ 0x0b, 0x0f, 0x11, 0x0f, 0x12, 0x12, 0x18);
+
+ return 0;
+}
+
+static const struct drm_display_mode gameforcechi_mode = {
+ .hdisplay = 640,
+ .hsync_start = 640 + 40,
+ .hsync_end = 640 + 40 + 2,
+ .htotal = 640 + 40 + 2 + 80,
+ .vdisplay = 480,
+ .vsync_start = 480 + 17,
+ .vsync_end = 480 + 17 + 5,
+ .vtotal = 480 + 17 + 5 + 13,
+ .clock = 23546,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+ .width_mm = 71,
+ .height_mm = 53,
+};
+
+static const struct st7703_panel_desc gameforcechi_desc = {
+ .mode = &gameforcechi_mode,
+ .lanes = 2,
+ .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM,
+ .format = MIPI_DSI_FMT_RGB888,
+ .init_sequence = gameforcechi_init_sequence,
+};
+
static int st7703_enable(struct drm_panel *panel)
{
struct st7703 *ctx = panel_to_st7703(panel);
@@ -887,6 +973,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi)
static const struct of_device_id st7703_of_match[] = {
{ .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc },
+ { .compatible = "gameforce,chi-panel", .data = &gameforcechi_desc },
{ .compatible = "powkiddy,rgb10max3-panel", .data = &rgb10max3_panel_desc },
{ .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc },
{ .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc },
--
2.34.1
^ permalink raw reply related
* [PATCH 2/5] dt-bindings: display: Add GameForce Chi Panel
From: Chris Morgan @ 2024-03-25 13:49 UTC (permalink / raw)
To: linux-rockchip
Cc: dri-devel, devicetree, daniel, airlied, sam, quic_jesszhan,
neil.armstrong, megi, kernel, agx, heiko, conor+dt,
krzysztof.kozlowski+dt, robh, Chris Morgan
In-Reply-To: <20240325134959.11807-1-macroalpha82@gmail.com>
From: Chris Morgan <macromorgan@hotmail.com>
The GameForce Chi panel is a panel specific to the GameForce Chi
handheld device that measures 3.5" diagonally with a resolution of
640x480.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
.../devicetree/bindings/display/panel/rocktech,jh057n00900.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
index 6ec471284f97..4ae152cc55e0 100644
--- a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
+++ b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml
@@ -22,6 +22,8 @@ properties:
enum:
# Anberic RG353V-V2 5.0" 640x480 TFT LCD panel
- anbernic,rg353v-panel-v2
+ # GameForce Chi 3.5" 640x480 TFT LCD panel
+ - gameforce,chi-panel
# Powkiddy RGB10MAX3 5.0" 720x1280 TFT LCD panel
- powkiddy,rgb10max3-panel
# Powkiddy RGB30 3.0" 720x720 TFT LCD panel
--
2.34.1
^ permalink raw reply related
* [PATCH 1/5] dt-bindings: vendor-prefix: Add prefix for GameForce
From: Chris Morgan @ 2024-03-25 13:49 UTC (permalink / raw)
To: linux-rockchip
Cc: dri-devel, devicetree, daniel, airlied, sam, quic_jesszhan,
neil.armstrong, megi, kernel, agx, heiko, conor+dt,
krzysztof.kozlowski+dt, robh, Chris Morgan
In-Reply-To: <20240325134959.11807-1-macroalpha82@gmail.com>
From: Chris Morgan <macromorgan@hotmail.com>
GameForce is a company that produces handheld game consoles.
https://gameforce.fun/
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b97d298b3eb6..3def72060414 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -529,6 +529,8 @@ patternProperties:
description: FX Technology Ltd.
"^galaxycore,.*":
description: GalaxyCore Inc.
+ "^gameforce,.*":
+ description: GameForce
"^gardena,.*":
description: GARDENA GmbH
"^gateway,.*":
--
2.34.1
^ permalink raw reply related
* [PATCH 0/5] Add Support for RK3326 GameForce Chi
From: Chris Morgan @ 2024-03-25 13:49 UTC (permalink / raw)
To: linux-rockchip
Cc: dri-devel, devicetree, daniel, airlied, sam, quic_jesszhan,
neil.armstrong, megi, kernel, agx, heiko, conor+dt,
krzysztof.kozlowski+dt, robh, Chris Morgan
From: Chris Morgan <macromorgan@hotmail.com>
Add support for the GameForce Chi [1].
The GameForce Chi has the following hardware:
Tested:
- 3.5" dual lane 640x480 DSI display.
- 15 GPIO based face buttons.
- 2 ADC based face buttons.
- 1 ADC joystick (left) connected to internal SARADC.
- RGB LED arrays for key backlighting
- Dual internal speakers.
- Realtek RTL8723BS SDIO WiFi.
- Single SDMMC slot.
Not Working (with notes in device-tree):
- Bluetooth - missing firmware
- 1 ADC joystick (right) connected to unknown UART based ADC.
[1] https://gameforce.fun/pages/gallery-of-gameforce-retro-gaming-handheld
Chris Morgan (5):
dt-bindings: vendor-prefix: Add prefix for GameForce
dt-bindings: display: Add GameForce Chi Panel
drm/panel: st7703: Add GameForce Chi Panel Support
dt-bindings: arm: rockchip: Add GameForce Chi
arm64: dts: rockchip: Add GameForce Chi
.../devicetree/bindings/arm/rockchip.yaml | 5 +
.../display/panel/rocktech,jh057n00900.yaml | 2 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
arch/arm64/boot/dts/rockchip/Makefile | 1 +
.../dts/rockchip/rk3326-gameforce-chi.dts | 811 ++++++++++++++++++
drivers/gpu/drm/panel/panel-sitronix-st7703.c | 87 ++
6 files changed, 908 insertions(+)
create mode 100644 arch/arm64/boot/dts/rockchip/rk3326-gameforce-chi.dts
--
2.34.1
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: mailbox: arm,mhuv3: Add bindings
From: Rob Herring @ 2024-03-25 13:44 UTC (permalink / raw)
To: Cristian Marussi
Cc: linux-kernel, linux-arm-kernel, devicetree, sudeep.holla,
jassisinghbrar, krzysztof.kozlowski+dt, conor+dt
In-Reply-To: <20240325092808.117510-2-cristian.marussi@arm.com>
On Mon, Mar 25, 2024 at 4:28 AM Cristian Marussi
<cristian.marussi@arm.com> wrote:
>
> Add bindings for the ARM MHUv3 Mailbox controller.
>
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> ---
> .../bindings/mailbox/arm,mhuv3.yaml | 239 ++++++++++++++++++
> 1 file changed, 239 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
>
> diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml b/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
> new file mode 100644
> index 000000000000..bfb8ec341d26
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
> @@ -0,0 +1,239 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mailbox/arm,mhuv3.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: ARM MHUv3 Mailbox Controller
> +
> +maintainers:
> + - Sudeep Holla <sudeep.holla@arm.com>
> + - Cristian Marussi <cristian.marussi@arm.com>
> +
> +description: |
> + The Arm Message Handling Unit (MHU) Version 3 is a mailbox controller that
> + enables unidirectional communications with remote processors through various
> + possible transport protocols.
> + The controller can optionally support a varying number of extensions that, in
> + turn, enable different kinds of transport to be used for communication.
> + Number, type and characteristics of each supported extension can be discovered
> + dynamically at runtime.
> +
> + Given the unidirectional nature of the controller, an MHUv3 mailbox controller
> + is composed of a MHU Sender (MHUS) containing a PostBox (PBX) block and a MHU
> + Receiver (MHUR) containing a MailBox (MBX) block, where
> +
> + PBX is used to
> + - Configure the MHU
> + - Send Transfers to the Receiver
> + - Optionally receive acknowledgment of a Transfer from the Receiver
> +
> + MBX is used to
> + - Configure the MHU
> + - Receive Transfers from the Sender
> + - Optionally acknowledge Transfers sent by the Sender
> +
> + Both PBX and MBX need to be present and defined in the DT description if you
> + need to establish a bidirectional communication, since you will have to
> + acquire two distinct unidirectional channels, one for each block.
> +
> + As a consequence both blocks needs to be represented separately and specified
> + as distinct DT nodes in order to properly describe their resources.
> +
> + Note that, though, thanks to the runtime discoverability, there is no need to
> + identify the type of blocks with distinct compatibles.
> +
> + Following are the MHUv3 possible extensions.
> +
> + - Doorbell Extension (DBE): DBE defines a type of channel called a Doorbell
> + Channel (DBCH). DBCH enables a single bit Transfer to be sent from the
> + Sender to Receiver. The Transfer indicates that an event has occurred.
> + When DBE is implemented, the number of DBCHs implemented is between 1 and
> + 128, numbered starting from 0 in ascending order.
> + Each DBCH contains 32 individual fields, referred to as flags, each of which
> + can be used independently. It is possible for the Sender to send multiple
> + Transfers at once using a single DBCH, so long as each Transfer uses
> + a different flag in the DBCH.
> + Optionally, data may be transmitted through an out-of-band shared memory
> + region, wherein the MHU Doorbell is used strictly as an interrupt generation
> + mechanism, but this is out of the scope of these bindings.
> +
> + - FastChannel Extension (FCE): FCE defines a type of channel called a Fast
> + Channel (FCH). FCH is intended for lower overhead communication between
> + Sender and Receiver at the expense of determinism. An FCH allows the Sender
> + to update the channel value at any time, regardless of whether the previous
> + value has been seen by the Receiver. When the Receiver reads the channel's
> + content it gets the last value written to the channel.
> + FCH is considered lossy in nature, and means that the Sender has no way of
> + knowing if, or when, the Receiver will act on the Transfer.
> + FCHs are expected to behave as RAM which generates interrupts when writes
> + occur to the locations within the RAM.
> + When FCE is implemented, the number of FCH that an implementation of the MHU
> + can support is between 1-1024, if the Fast Channel word-size is 32-bits, or
> + between 1-512, when the Fast Channel word-size is 64-bits.
Be consistent: FastChannel
> + FCHs are numbered from 0 in ascending order.
> + Note that Fast Channel word-size is implementation defined, not configurable
> + but discoverable at run-time.
> + Optionally, data may be transmitted through an out-of-band shared memory
> + region, wherein the MHU FastChannel is used as an interrupt generation
> + mechanism which carries also a pointer to such out-of-band data, but this
> + is out of the scope of these bindings.
> +
> + - FIFO Extension (FE): FE defines a Channel type called a FIFO Channel (FFCH).
> + FFCH allows a Sender to send
> + - Multiple Transfer to the Receiver without having to wait for a previous
> + Transfer to be acknowledged by the Receiver, as long as the FIFO has
> + room for the Transfer.
> + - Transfers which require the Receiver to provide acknowledgment.
> + - Transfers which have in-band payload.
> + In all cases, the data is guaranteed to be observed by the Receiver in the
> + same order which the Sender sent it.
> + When FE is implemented, the number of FFCH an implementation of the MHU can
> + support is between 1 and 64, numbered starting from the 0 in ascending
> + order. The FIFO size is implementation defined and not configurable.
Size is discoverable or opaque to s/w?
> + Optionally, additional data may be transmitted through an out-of-band shared
> + memory region, wherein the MHU FIFO is used to transmit, in order, a small
> + part of the payload (like a header) and a reference to the shared memory
> + area holding the remaining, bigger, chunk of the payload, but this is out of
> + the scope of these bindings.
> +
> +properties:
> + compatible:
> + const: arm,mhuv3
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + minItems: 1
> + maxItems: 38
> +
> + interrupt-names:
> + description: |
> + The MHUv3 controller generates a number of events some of which are used
> + to generate interrupts; as a consequence it can expose a varying number of
> + optional PBX/MBX interrupts, representing the events generated during the
> + operation of the various transport protocols associated with different
> + extensions. All interrupts of the MHU are level-sensitive.
> + Some of these optional interrupts are defined per-channel, where the
> + number of channels effectively available is implementation defined and
> + run-time discoverable.
> + In the following, for sake of simplicity, only a limited number of
> + per-channel interrupt names are enumerated, out of all the possible
> + channels allowed by the specification for each extension type.
> +
> + - "combined": PBX/MBX Combined interrupt
> + - "combined-ffch": PBX/MBX FIFO Combined interrupt
> + - "ffch-low-tide-<N>": PBX/MBX FIFO Channel <N> Low Tide interrupt
> + - "ffch-high-tide-<N>": PBX/MBX FIFO Channel <N> High Tide interrupt
> + - "ffch-flush-<N>": PBX/MBX FIFO Channel <N> Flush interrupt
> + - "mbx-dbch-xfer-<N>": MBX Doorbell Channel <N> Transfer interrupt
> + - "mbx-fch-xfer-<N>": MBX Fast Channel <N> Transfer interrupt
> + - "mbx-fchgrp-xfer-<N>": MBX Fast Channel <N> Group Transfer interrupt
> + - "mbx-ffch-xfer-<N>": MBX FIFO Channel <N> Transfer interrupt
> + - "pbx-dbch-xfer-ack-<N>": PBX Doorbell Channel <N> Transfer Ack interrupt
> + - "pbx-ffch-xfer-ack-<N>": PBX FIFO Channel <N> Transfer Ack interrupt
It would be better to not define these strings twice. You can do
something like this:
items:
oneOf:
- const: combined
description: ...
- pattern: '^ffch-low-tide-[0-9]+$'
description: ...
And so on.
> +
> + The only mandatory interrupts on the MHU are:
> + - combined
> + - mbx-fch-xfer-<N> but only if mbx-fcgrp-xfer-<N> is not implemented.
> +
> + minItems: 1
> + maxItems: 38
Perhaps a comment on where 38 comes from. AIUI, this is a "should be
enough for now" value.
> + items:
> + enum:
> + - combined
> + - combined-ffch
> + - ffch-low-tide-0
> + - ffch-low-tide-1
> + - ffch-low-tide-2
> + - ffch-low-tide-3
> + - ffch-high-tide-0
> + - ffch-high-tide-1
> + - ffch-high-tide-2
> + - ffch-high-tide-3
> + - ffch-flush-0
> + - ffch-flush-1
> + - ffch-flush-2
> + - ffch-flush-3
> + - mbx-dbch-xfer-0
> + - mbx-dbch-xfer-1
> + - mbx-dbch-xfer-2
> + - mbx-dbch-xfer-3
> + - mbx-fch-xfer-0
> + - mbx-fch-xfer-1
> + - mbx-fch-xfer-2
> + - mbx-fch-xfer-3
> + - mbx-fchgrp-xfer-0
> + - mbx-fchgrp-xfer-1
> + - mbx-fchgrp-xfer-2
> + - mbx-fchgrp-xfer-3
> + - mbx-ffch-xfer-0
> + - mbx-ffch-xfer-1
> + - mbx-ffch-xfer-2
> + - mbx-ffch-xfer-3
> + - pbx-dbch-xfer-ack-0
> + - pbx-dbch-xfer-ack-1
> + - pbx-dbch-xfer-ack-2
> + - pbx-dbch-xfer-ack-3
> + - pbx-ffch-xfer-ack-0
> + - pbx-ffch-xfer-ack-1
> + - pbx-ffch-xfer-ack-2
> + - pbx-ffch-xfer-ack-3
> +
> + '#mbox-cells':
> + description: |
> + The first argument in the consumers 'mboxes' property represents the
> + extension type, the second is for the channel number while the third
> + depends on extension type.
> +
> + Extension type for DBE is 0 and the third parameter represents the
> + doorbell flag number to use.
> + Extension type for FCE is 1, third parameter unused.
> + Extension type for FE is 2, third parameter unused.
> +
> + mboxes = <&mhu 0 0 5>; // DBE, Doorbell Channel Window 0, doorbell flag 5.
> + mboxes = <&mhu 0 1 7>; // DBE, Doorbell Channel Window 1, doorbell flag 7.
> + mboxes = <&mhu 1 0 0>; // FCE, Fast Channel Window 0.
> + mboxes = <&mhu 1 3 0>; // FCE, Fast Channel Window 3.
> + mboxes = <&mhu 2 1 0>; // FE, FIFO Channel Window 1.
> + mboxes = <&mhu 2 7 0>; // FE, FIFO Channel Window 7.
> + const: 3
> +
> + clocks:
> + maxItems: 1
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - interrupt-names
> + - '#mbox-cells'
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + mhu_tx: mailbox@2aaa0000 {
Drop unused labels.
> + compatible = "arm,mhuv3";
> + #mbox-cells = <3>;
> + reg = <0 0x2aaa0000 0 0x10000>;
> + clocks = <&clock 0>;
> + interrupt-names = "combined", "pbx-dbch-xfer-ack-1",
> + "ffch-high-tide-0";
> + interrupts = <0 36 4>, <0 37 4>;
> + };
> +
> + mhu_rx: mailbox@2ab00000 {
> + compatible = "arm,mhuv3";
> + #mbox-cells = <3>;
> + reg = <0 0x2aab0000 0 0x10000>;
> + clocks = <&clock 0>;
> + interrupt-names = "combined", "mbx-dbch-xfer-1", "ffch-low-tide-0";
> + interrupts = <0 35 4>, <0 38 4>, <0 39 4>;
> + };
> + };
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH 2/2] iio: adc: Add support for AD4000
From: David Lechner @ 2024-03-25 13:35 UTC (permalink / raw)
To: Marcelo Schmitt
Cc: lars, Michael.Hennerich, jic23, robh+dt, krzysztof.kozlowski+dt,
conor+dt, marcelo.schmitt1, linux-iio, devicetree, linux-kernel
In-Reply-To: <CAMknhBH7umcBD0hyt=6fOKu9E8k=CSrnNE4Z+9ynn0F4B=Wk2w@mail.gmail.com>
On Sat, Mar 23, 2024 at 4:53 PM David Lechner <dlechner@baylibre.com> wrote:
>
> On Fri, Mar 22, 2024 at 5:06 PM Marcelo Schmitt
> <marcelo.schmitt@analog.com> wrote:
> >
...
> > +
> > + vref_reg = devm_regulator_get(&spi->dev, "vref");
>
> This should to be devm_regulator_get_optional(), otherwise it can
> return a "dummy" regulator if one is missing in the devicetree which
> will fail when getting the voltage.
>
> > + if (IS_ERR(vref_reg))
> > + return dev_err_probe(&spi->dev, PTR_ERR(vref_reg),
> > + "Failed to get vref regulator\n");
> > +
> > + ret = regulator_enable(vref_reg);
> > + if (ret < 0)
> > + return dev_err_probe(&spi->dev, ret,
> > + "Failed to enable voltage regulator\n");
> > +
> > + ret = devm_add_action_or_reset(&spi->dev, ad4000_regulator_disable, vref_reg);
> > + if (ret)
> > + return dev_err_probe(&spi->dev, ret,
> > + "Failed to add regulator disable action\n");
> > +
> > + st->vref = regulator_get_voltage(vref_reg);
> > + if (st->vref < 0)
> > + return dev_err_probe(&spi->dev, st->vref, "Failed to get vref\n");
> > +
> > + if (!device_property_present(&spi->dev, "adi,spi-cs-mode")) {
> > + st->cnv_gpio = devm_gpiod_get(&spi->dev, "cnv", GPIOD_OUT_HIGH);
> > + if (IS_ERR(st->cnv_gpio)) {
> > + if (PTR_ERR(st->cnv_gpio) == -EPROBE_DEFER)
> > + return -EPROBE_DEFER;
> > +
> > + return dev_err_probe(&spi->dev, PTR_ERR(st->cnv_gpio),
> > + "Failed to get CNV GPIO");
> > + }
> > + }
>
In a review for a different patch, Jonathan said he would prefer
devm_regulator_get() and failing in regulator_get_voltage() rather
than using devm_regulator_get_optional() so I think the same would
apply here and my suggestion should be overruled.
^ permalink raw reply
* Re: [PATCH v4 4/4] arm64: dts: S32G3: Introduce device tree for S32G-VNP-RDB3
From: Ghennadi Procopciuc @ 2024-03-25 13:34 UTC (permalink / raw)
To: Wadim Mueller, Shawn Guo
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ulf Hansson,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Greg Kroah-Hartman, Jiri Slaby, Chester Lin,
Andreas Färber, Matthias Brugger, NXP S32 Linux Team,
Tim Harvey, Marco Felsch, Marek Vasut, Gregor Herburger,
Hugo Villeneuve, Joao Paulo Goncalves, Markus Niebel,
Matthias Schiffer, Stefan Wahren, Bjorn Helgaas,
Philippe Schenker, Josua Mayer, Li Yang, devicetree, linux-kernel,
linux-mmc, linux-arm-kernel, linux-serial
In-Reply-To: <20240325132634.GA33097@bhlegrsu.conti.de>
On 3/25/24 15:26, Wadim Mueller wrote:
> On Mon, Mar 25, 2024 at 11:30:38AM +0200, Ghennadi Procopciuc wrote:
>> On 3/24/24 23:43, Wadim Mueller wrote:
>>> This commit adds device tree support for the NXP S32G3-based
>>> S32G-VNP-RDB3 Board [1].
>>>
>>> The S32G3 features an 8-core ARM Cortex-A53 based SoC developed by NXP.
>>>
>>> The device tree files are derived from the official NXP downstream
>>> Linux tree [2].
>>>
>>> This addition encompasses a limited selection of peripherals that
>>> are upstream-supported. Apart from the ARM System Modules
>>> (GIC, Generic Timer, etc.), the following IPs have been validated:
>>>
>>> * UART: fsl-linflexuart
>>> * SDHC: fsl-imx-esdhc
>>>
>>> Clock settings for the chip rely on ATF Firmware [3].
>>> Pin control integration into the device tree is pending and currently
>>> relies on Firmware/U-Boot settings [4].
>>>
>>> These changes were validated using BSP39 Firmware/U-Boot from NXP [5].
>>>
>>> The modifications enable booting the official Ubuntu 22.04 from NXP on
>>> the RDB3 with default settings from the SD card and eMMC.
>>>
>>> [1] https://www.nxp.com/design/design-center/designs/s32g3-vehicle-networking-reference-design:S32G-VNP-RDB3
>>> [2] https://github.com/nxp-auto-linux/linux
>>> [3] https://github.com/nxp-auto-linux/arm-trusted-firmware
>>> [4] https://github.com/nxp-auto-linux/u-boot
>>> [5] https://github.com/nxp-auto-linux/auto_yocto_bsp
>>>
>>> Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
>>> ---
>>
>> Thank you, Wadim, for bringing up the S32G3RDB3 board! The board boots
>> with all 8 cores. The log is attached below.
>>
>
> Thanks for testing Ghennadi, much appreciated.
>
> According to MAINTAINERS all "dts/freescale/" DTS files
> needs to go through the IMX/MXC tree?
> Is my understanding correct? Just asking whether I understand the file
> content correctly!
>
Indeed, everything should go through the IMX tree.
Here [0] you can find a long discussion about this.
[0]
https://lore.kernel.org/linux-arm-kernel/a5f7b53a-6b44-4f0b-83f2-b055b8aa3b2d@suse.com/
Regards,
Ghennadi
^ permalink raw reply
* Re: [PATCH v4 4/4] arm64: dts: S32G3: Introduce device tree for S32G-VNP-RDB3
From: Wadim Mueller @ 2024-03-25 13:26 UTC (permalink / raw)
To: Ghennadi Procopciuc
Cc: Wadim Mueller, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Ulf Hansson, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, NXP Linux Team, Greg Kroah-Hartman, Jiri Slaby,
Chester Lin, Andreas Färber, Matthias Brugger,
NXP S32 Linux Team, Tim Harvey, Marco Felsch, Marek Vasut,
Gregor Herburger, Hugo Villeneuve, Joao Paulo Goncalves,
Markus Niebel, Matthias Schiffer, Stefan Wahren, Bjorn Helgaas,
Philippe Schenker, Josua Mayer, Li Yang, devicetree, linux-kernel,
linux-mmc, linux-arm-kernel, linux-serial
In-Reply-To: <df6f2a09-8125-4c1a-9dfd-3217233dc076@oss.nxp.com>
On Mon, Mar 25, 2024 at 11:30:38AM +0200, Ghennadi Procopciuc wrote:
> On 3/24/24 23:43, Wadim Mueller wrote:
> > This commit adds device tree support for the NXP S32G3-based
> > S32G-VNP-RDB3 Board [1].
> >
> > The S32G3 features an 8-core ARM Cortex-A53 based SoC developed by NXP.
> >
> > The device tree files are derived from the official NXP downstream
> > Linux tree [2].
> >
> > This addition encompasses a limited selection of peripherals that
> > are upstream-supported. Apart from the ARM System Modules
> > (GIC, Generic Timer, etc.), the following IPs have been validated:
> >
> > * UART: fsl-linflexuart
> > * SDHC: fsl-imx-esdhc
> >
> > Clock settings for the chip rely on ATF Firmware [3].
> > Pin control integration into the device tree is pending and currently
> > relies on Firmware/U-Boot settings [4].
> >
> > These changes were validated using BSP39 Firmware/U-Boot from NXP [5].
> >
> > The modifications enable booting the official Ubuntu 22.04 from NXP on
> > the RDB3 with default settings from the SD card and eMMC.
> >
> > [1] https://www.nxp.com/design/design-center/designs/s32g3-vehicle-networking-reference-design:S32G-VNP-RDB3
> > [2] https://github.com/nxp-auto-linux/linux
> > [3] https://github.com/nxp-auto-linux/arm-trusted-firmware
> > [4] https://github.com/nxp-auto-linux/u-boot
> > [5] https://github.com/nxp-auto-linux/auto_yocto_bsp
> >
> > Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
> > ---
>
> Thank you, Wadim, for bringing up the S32G3RDB3 board! The board boots
> with all 8 cores. The log is attached below.
>
Thanks for testing Ghennadi, much appreciated.
According to MAINTAINERS all "dts/freescale/" DTS files
needs to go through the IMX/MXC tree?
Is my understanding correct? Just asking whether I understand the file
content correctly!
> Tested-by: Ghennadi Procopciuc <ghennadi.procopciuc@oss.nxp.com>
> Reviewed-by: Ghennadi Procopciuc <ghennadi.procopciuc@oss.nxp.com>
>
> Starting kernel ...
>
> [ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
> [ 0.000000] Linux version 6.9.0-rc1-00004-gcb630dd69df3
> (nxa06643@lxl00026) (aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12)
> 7.5.0, GNU ld (Linaro_Binutils-2019.12) 2.28.2.20170706) #21 SMP PREEMPT
> Mon Mar 25 10:50:16 EET 2024
> [ 0.000000] KASLR disabled due to lack of seed
> [ 0.000000] Machine model: NXP S32G3 Reference Design Board 3
> (S32G-VNP-RDB3)
> [ 0.000000] efi: UEFI not found.
> [ 0.000000] OF: reserved mem: 0x00000000d0000000..0x00000000d000007f
> (0 KiB) nomap non-reusable shm@d0000000
> [ 0.000000] OF: reserved mem: 0x00000000ff600000..0x00000000ff7fffff
> (2048 KiB) nomap non-reusable atf@ff600000
> [ 0.000000] earlycon: linflex0 at MMIO 0x00000000401c8000 (options
> '115200n8')
> [ 0.000000] printk: legacy bootconsole [linflex0] enabled
> [ 0.000000] NUMA: No NUMA configuration found
> [ 0.000000] NUMA: Faking a node at [mem
> 0x0000000080000000-0x00000008dfffffff]
> [ 0.000000] NUMA: NODE_DATA [mem 0x8df8ff9c0-0x8df901fff]
> [ 0.000000] Zone ranges:
> [ 0.000000] DMA [mem 0x0000000080000000-0x00000000ffffffff]
> [ 0.000000] DMA32 empty
> [ 0.000000] Normal [mem 0x0000000100000000-0x00000008dfffffff]
> [ 0.000000] Movable zone start for each node
> [ 0.000000] Early memory node ranges
> [ 0.000000] node 0: [mem 0x0000000080000000-0x00000000cfffffff]
> [ 0.000000] node 0: [mem 0x00000000d0001000-0x00000000ff5fffff]
> [ 0.000000] node 0: [mem 0x00000000ff600000-0x00000000ff7fffff]
> [ 0.000000] node 0: [mem 0x00000000ff800000-0x00000000ffffffff]
> [ 0.000000] node 0: [mem 0x0000000880000000-0x00000008dfffffff]
> [ 0.000000] Initmem setup node 0 [mem
> 0x0000000080000000-0x00000008dfffffff]
> [ 0.000000] On node 0, zone DMA: 1 pages in unavailable ranges
> [ 0.000000] cma: Reserved 32 MiB at 0x00000000fd600000 on node -1
> [ 0.000000] psci: probing for conduit method from DT.
> [ 0.000000] psci: PSCIv1.1 detected in firmware.
> [ 0.000000] psci: Using standard PSCI v0.2 function IDs
> [ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
> [ 0.000000] psci: SMC Calling Convention v1.2
> [ 0.000000] percpu: Embedded 24 pages/cpu s57896 r8192 d32216 u98304
> [ 0.000000] Detected VIPT I-cache on CPU0
> [ 0.000000] CPU features: detected: GIC system register CPU interface
> [ 0.000000] CPU features: detected: ARM erratum 845719
> [ 0.000000] alternatives: applying boot alternatives
> [ 0.000000] Kernel command line: console=ttyLF0,115200
> root=/dev/mmcblk0p2 rootwait rw earlycon
> [ 0.000000] Dentry cache hash table entries: 524288 (order: 10,
> 4194304 bytes, linear)
> [ 0.000000] Inode-cache hash table entries: 262144 (order: 9, 2097152
> bytes, linear)
> [ 0.000000] Fallback order for Node 0: 0
> [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 903167
> [ 0.000000] Policy zone: Normal
> [ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
> [ 0.000000] software IO TLB: area num 8.
> [ 0.000000] software IO TLB: mapped [mem
> 0x00000000f9600000-0x00000000fd600000] (64MB)
> [ 0.000000] Memory: 3451804K/3670012K available (17472K kernel code,
> 4790K rwdata, 11432K rodata, 9984K init, 754K bss, 185440K reserved,
> 32768K cma-reserved)
> [ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=8, Nodes=1
> [ 0.000000] rcu: Preemptible hierarchical RCU implementation.
> [ 0.000000] rcu: RCU event tracing is enabled.
> [ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=512 to
> nr_cpu_ids=8.
> [ 0.000000] Trampoline variant of Tasks RCU enabled.
> [ 0.000000] Tracing variant of Tasks RCU enabled.
> [ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay
> is 25 jiffies.
> [ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=8
> [ 0.000000] RCU Tasks: Setting shift to 3 and lim to 1
> rcu_task_cb_adjust=1.
> [ 0.000000] RCU Tasks Trace: Setting shift to 3 and lim to 1
> rcu_task_cb_adjust=1.
> [ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
> [ 0.000000] GICv3: 544 SPIs implemented
> [ 0.000000] GICv3: 0 Extended SPIs implemented
> [ 0.000000] Root IRQ handler: gic_handle_irq
> [ 0.000000] GICv3: GICv3 features: 16 PPIs
> [ 0.000000] GICv3: CPU0: found redistributor 0 region
> 0:0x0000000050900000
> [ 0.000000] ITS: No ITS available, not enabling LPIs
> [ 0.000000] rcu: srcu_init: Setting srcu_struct sizes based on
> contention.
> [ 0.000000] arch_timer: cp15 timer(s) running at 5.00MHz (virt).
> [ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff
> max_cycles: 0x127350b88, max_idle_ns: 440795202120 ns
> [ 0.000001] sched_clock: 56 bits at 5MHz, resolution 200ns, wraps
> every 4398046511100ns
> [ 0.008224] Console: colour dummy device 80x25
> [ 0.012493] Calibrating delay loop (skipped), value calculated using
> timer frequency.. 10.00 BogoMIPS (lpj=20000)
> [ 0.022661] pid_max: default: 32768 minimum: 301
> [ 0.027333] LSM: initializing lsm=capability
> [ 0.031604] Mount-cache hash table entries: 8192 (order: 4, 65536
> bytes, linear)
> [ 0.038904] Mountpoint-cache hash table entries: 8192 (order: 4,
> 65536 bytes, linear)
> [ 0.047831] cacheinfo: Unable to detect cache hierarchy for CPU 0
> [ 0.054481] rcu: Hierarchical SRCU implementation.
> [ 0.058926] rcu: Max phase no-delay instances is 1000.
> [ 0.064746] EFI services will not be available.
> [ 0.069258] smp: Bringing up secondary CPUs ...
> [ 0.073964] Detected VIPT I-cache on CPU1
> [ 0.074018] GICv3: CPU1: found redistributor 1 region
> 0:0x0000000050920000
> [ 0.074056] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
> [ 0.074630] Detected VIPT I-cache on CPU2
> [ 0.074662] GICv3: CPU2: found redistributor 2 region
> 0:0x0000000050940000
> [ 0.074682] CPU2: Booted secondary processor 0x0000000002 [0x410fd034]
> [ 0.075227] Detected VIPT I-cache on CPU3
> [ 0.075258] GICv3: CPU3: found redistributor 3 region
> 0:0x0000000050960000
> [ 0.075277] CPU3: Booted secondary processor 0x0000000003 [0x410fd034]
> [ 0.075831] Detected VIPT I-cache on CPU4
> [ 0.075885] GICv3: CPU4: found redistributor 100 region
> 0:0x0000000050980000
> [ 0.075917] CPU4: Booted secondary processor 0x0000000100 [0x410fd034]
> [ 0.076492] Detected VIPT I-cache on CPU5
> [ 0.076527] GICv3: CPU5: found redistributor 101 region
> 0:0x00000000509a0000
> [ 0.076547] CPU5: Booted secondary processor 0x0000000101 [0x410fd034]
> [ 0.077090] Detected VIPT I-cache on CPU6
> [ 0.077127] GICv3: CPU6: found redistributor 102 region
> 0:0x00000000509c0000
> [ 0.077147] CPU6: Booted secondary processor 0x0000000102 [0x410fd034]
> [ 0.077724] Detected VIPT I-cache on CPU7
> [ 0.077765] GICv3: CPU7: found redistributor 103 region
> 0:0x00000000509e0000
> [ 0.077785] CPU7: Booted secondary processor 0x0000000103 [0x410fd034]
> [ 0.077896] smp: Brought up 1 node, 8 CPUs
> [ 0.203873] SMP: Total of 8 processors activated.
> [ 0.208551] CPU: All CPU(s) started at EL1
> [ 0.212660] CPU features: detected: 32-bit EL0 Support
> [ 0.217751] CPU features: detected: 32-bit EL1 Support
> [ 0.222885] CPU features: detected: CRC32 instructions
> [ 0.228042] alternatives: applying system-wide alternatives
> [ 0.236019] devtmpfs: initialized
> [ 0.242628] clocksource: jiffies: mask: 0xffffffff max_cycles:
> 0xffffffff, max_idle_ns: 7645041785100000 ns
> [ 0.252037] futex hash table entries: 2048 (order: 5, 131072 bytes,
> linear)
> [ 0.260021] pinctrl core: initialized pinctrl subsystem
> [ 0.266046] DMI not present or invalid.
> [ 0.272094] NET: Registered PF_NETLINK/PF_ROUTE protocol family
> [ 0.278654] DMA: preallocated 512 KiB GFP_KERNEL pool for atomic
> allocations
> [ 0.285546] DMA: preallocated 512 KiB GFP_KERNEL|GFP_DMA pool for
> atomic allocations
> [ 0.293318] DMA: preallocated 512 KiB GFP_KERNEL|GFP_DMA32 pool for
> atomic allocations
> [ 0.301019] audit: initializing netlink subsys (disabled)
> [ 0.306513] audit: type=2000 audit(0.180:1): state=initialized
> audit_enabled=0 res=1
> [ 0.307304] thermal_sys: Registered thermal governor 'step_wise'
> [ 0.314096] thermal_sys: Registered thermal governor 'power_allocator'
> [ 0.320130] cpuidle: using governor menu
> [ 0.330730] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
> [ 0.337396] ASID allocator initialised with 65536 entries
> [ 0.344482] Serial: AMBA PL011 UART driver
> [ 0.350914] Modules: 21600 pages in range for non-PLT usage
> [ 0.350920] Modules: 513120 pages in range for PLT usage
> [ 0.356758] HugeTLB: registered 1.00 GiB page size, pre-allocated 0 pages
> [ 0.368493] HugeTLB: 0 KiB vmemmap can be freed for a 1.00 GiB page
> [ 0.374744] HugeTLB: registered 32.0 MiB page size, pre-allocated 0 pages
> [ 0.381511] HugeTLB: 0 KiB vmemmap can be freed for a 32.0 MiB page
> [ 0.387762] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
> [ 0.394531] HugeTLB: 0 KiB vmemmap can be freed for a 2.00 MiB page
> [ 0.400784] HugeTLB: registered 64.0 KiB page size, pre-allocated 0 pages
> [ 0.407551] HugeTLB: 0 KiB vmemmap can be freed for a 64.0 KiB page
> [ 0.414206] Demotion targets for Node 0: null
> [ 0.419168] ACPI: Interpreter disabled.
> [ 0.423692] iommu: Default domain type: Translated
> [ 0.428153] iommu: DMA domain TLB invalidation policy: strict mode
> [ 0.434805] SCSI subsystem initialized
> [ 0.438513] usbcore: registered new interface driver usbfs
> [ 0.443706] usbcore: registered new interface driver hub
> [ 0.448995] usbcore: registered new device driver usb
> [ 0.454351] pps_core: LinuxPPS API ver. 1 registered
> [ 0.458968] pps_core: Software ver. 5.3.6 - Copyright 2005-2007
> Rodolfo Giometti <giometti@linux.it>
> [ 0.468095] PTP clock support registered
> [ 0.472054] EDAC MC: Ver: 3.0.0
> [ 0.475481] scmi_core: SCMI protocol bus registered
> [ 0.480546] FPGA manager framework
> [ 0.483666] Advanced Linux Sound Architecture Driver Initialized.
> [ 0.490590] vgaarb: loaded
> [ 0.493333] clocksource: Switched to clocksource arch_sys_counter
> [ 0.499297] VFS: Disk quotas dquot_6.6.0
> [ 0.503017] VFS: Dquot-cache hash table entries: 512 (order 0, 4096
> bytes)
> [ 0.510017] pnp: PnP ACPI: disabled
> [ 0.519430] NET: Registered PF_INET protocol family
> [ 0.524185] IP idents hash table entries: 65536 (order: 7, 524288
> bytes, linear)
> [ 0.533803] tcp_listen_portaddr_hash hash table entries: 2048 (order:
> 3, 32768 bytes, linear)
> [ 0.542061] Table-perturb hash table entries: 65536 (order: 6, 262144
> bytes, linear)
> [ 0.549719] TCP established hash table entries: 32768 (order: 6,
> 262144 bytes, linear)
> [ 0.557803] TCP bind hash table entries: 32768 (order: 8, 1048576
> bytes, linear)
> [ 0.566154] TCP: Hash tables configured (established 32768 bind 32768)
> [ 0.572472] UDP hash table entries: 2048 (order: 4, 65536 bytes, linear)
> [ 0.579091] UDP-Lite hash table entries: 2048 (order: 4, 65536 bytes,
> linear)
> [ 0.586323] NET: Registered PF_UNIX/PF_LOCAL protocol family
> [ 0.592198] RPC: Registered named UNIX socket transport module.
> [ 0.597778] RPC: Registered udp transport module.
> [ 0.602457] RPC: Registered tcp transport module.
> [ 0.607143] RPC: Registered tcp-with-tls transport module.
> [ 0.612612] RPC: Registered tcp NFSv4.1 backchannel transport module.
> [ 0.619048] PCI: CLS 0 bytes, default 64
> [ 0.623428] kvm [1]: HYP mode not available
> [ 0.628384] Initialise system trusted keyrings
> [ 0.632632] workingset: timestamp_bits=42 max_order=20 bucket_order=0
> [ 0.639182] squashfs: version 4.0 (2009/01/31) Phillip Lougher
> [ 0.644948] NFS: Registering the id_resolver key type
> [ 0.649780] Key type id_resolver registered
> [ 0.653921] Key type id_legacy registered
> [ 0.657932] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
> [ 0.664597] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver
> Registering...
> [ 0.672111] 9p: Installing v9fs 9p2000 file system support
> [ 0.714617] Key type asymmetric registered
> [ 0.718368] Asymmetric key parser 'x509' registered
> [ 0.723278] Block layer SCSI generic (bsg) driver version 0.4 loaded
> (major 245)
> [ 0.730608] io scheduler mq-deadline registered
> [ 0.735119] io scheduler kyber registered
> [ 0.739144] io scheduler bfq registered
> [ 0.764751] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
> [ 0.773400] 401c8000.serial: ttyLF0 at MMIO 0x401c8000 (irq = 14,
> base_baud = 0) is a FSL_LINFLEX
> [ 0.783976] printk: legacy console [ttyLF0] enabled
> [ 0.783976] printk: legacy console [ttyLF0] enabled
> [ 0.793930] printk: legacy bootconsole [linflex0] disabled
> [ 0.793930] printk: legacy bootconsole [linflex0] disabled
> [ 0.809777] 401cc000.serial: ttyLF1 at MMIO 0x401cc000 (irq = 15,
> base_baud = 0) is a FSL_LINFLEX
> [ 0.819329] msm_serial: driver initialized
> [ 0.823695] SuperH (H)SCI(F) driver initialized
> [ 0.828378] STM32 USART driver initialized
> [ 0.840105] loop: module loaded
> [ 0.844169] megasas: 07.727.03.00-rc1
> [ 0.852986] tun: Universal TUN/TAP device driver, 1.6
> [ 0.858691] thunder_xcv, ver 1.0
> [ 0.862013] thunder_bgx, ver 1.0
> [ 0.865323] nicpf, ver 1.0
> [ 0.868818] hns3: Hisilicon Ethernet Network Driver for Hip08 Family
> - version
> [ 0.876179] hns3: Copyright (c) 2017 Huawei Corporation.
> [ 0.881621] hclge is initializing
> [ 0.885029] e1000: Intel(R) PRO/1000 Network Driver
> [ 0.889999] e1000: Copyright (c) 1999-2006 Intel Corporation.
> [ 0.895874] e1000e: Intel(R) PRO/1000 Network Driver
> [ 0.900932] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
> [ 0.906982] igb: Intel(R) Gigabit Ethernet Network Driver
> [ 0.912483] igb: Copyright (c) 2007-2014 Intel Corporation.
> [ 0.918195] igbvf: Intel(R) Gigabit Virtual Function Network Driver
> [ 0.924581] igbvf: Copyright (c) 2009 - 2012 Intel Corporation.
> [ 0.930796] sky2: driver version 1.30
> [ 0.935382] VFIO - User Level meta-driver version: 0.3
> [ 0.942227] usbcore: registered new interface driver usb-storage
> [ 0.950179] i2c_dev: i2c /dev entries driver
> [ 0.959203] sdhci: Secure Digital Host Controller Interface driver
> [ 0.965503] sdhci: Copyright(c) Pierre Ossman
> [ 0.970334] Synopsys Designware Multimedia Card Interface Driver
> [ 0.976987] sdhci-pltfm: SDHCI platform and OF driver helper
> [ 0.983975] ledtrig-cpu: registered to indicate activity on CPUs
> [ 0.990556] scmi_protocol scmi_dev.1: Enabled polling mode TX channel
> - prot_id:16
> [ 0.998513] arm-scmi firmware:scmi: SCMI Notifications - Core Enabled.
> [ 1.005209] arm-scmi firmware:scmi: SCMI Protocol v2.0 'NXP:S32G399A'
> Firmware version 0x0
> [ 1.014897] cpu cpu0: EM: only supports uW power values
> [ 1.025027] SMCCC: SOC_ID: ARCH_SOC_ID not implemented, skipping ....
> [ 1.032401] usbcore: registered new interface driver usbhid
> [ 1.038094] usbhid: USB HID core driver
> [ 1.044180] hw perfevents: enabled with armv8_cortex_a53 PMU driver,
> 7 counters available
> [ 1.056194] NET: Registered PF_PACKET protocol family
> [ 1.061445] 9pnet: Installing 9P2000 support
> [ 1.065867] Key type dns_resolver registered
> [ 1.079732] Timer migration: 1 hierarchy levels; 8 children per
> group; 1 crossnode level
> [ 1.088206] registered taskstats version 1
> [ 1.092820] Loading compiled-in X.509 certificates
> [ 1.115627] clk: Disabling unused clocks
> [ 1.117662] sdhci-esdhc-imx 402f0000.mmc: could not get pinctrl
> [ 1.119704] PM: genpd: Disabling unused power domains
> [ 1.130853] ALSA device list:
> [ 1.133886] No soundcards found.
> [ 1.157133] mmc0: SDHCI controller on 402f0000.mmc [402f0000.mmc]
> using ADMA
> [ 1.164512] Waiting for root device /dev/mmcblk0p2...
> [ 1.185787] mmc0: host does not support reading read-only switch,
> assuming write-enable
> [ 1.195000] mmc0: new high speed SDHC card at address 5048
> [ 1.201102] mmcblk0: mmc0:5048 SD32G 29.7 GiB
> [ 1.208397] mmcblk0: p1 p2
> [ 1.238459] EXT4-fs (mmcblk0p2): recovery complete
> [ 1.244613] EXT4-fs (mmcblk0p2): mounted filesystem
> 52830f5f-ab50-4125-a606-3c65100b7d4a r/w with ordered data mode. Quota
> mode: none.
> [ 1.257000] VFS: Mounted root (ext4 filesystem) on device 179:2.
> [ 1.264390] devtmpfs: mounted
> [ 1.271069] Freeing unused kernel memory: 9984K
> [ 1.275760] Run /sbin/init as init process
> [ 1.657291] systemd[1]: System time before build time, advancing clock.
> [ 1.714423] systemd[1]: systemd 250.5+ running in system mode (+PAM
> -AUDIT -SELINUX -APPARMOR +IMA -SMACK +SECCOMP -GCRYPT -GNUTLS -OPENSSL
> +ACL +BLKID -CURL -ELFUTILS -FIDO2 -IDN2 -IDN -IPTC +KMOD -LIBCRYPTSETUP
> +LIBFDISK -PCRE2 -PWQUALITY -P11KIT -QRENCODE -BZIP2 -LZ4 -XZ -ZLIB
> +ZSTD -BPF_FRAMEWORK +XKBCOMMON +UTMP +SYSVINIT default-hierarchy=hybrid)
> [ 1.746891] systemd[1]: Detected architecture arm64.
>
> Welcome to Auto Linux BSP develop (kirkstone)!
>
> [ 1.845928] systemd[1]: Hostname set to <s32g399ardb3>.
> [ 2.186158] systemd[1]: Binding to IPv6 address not available since
> kernel does not support IPv6.
> [ 2.195287] systemd[1]: Binding to IPv6 address not available since
> kernel does not support IPv6.
> [ 2.317364] systemd[1]: Queued start job for default target
> Multi-User System.
> [ 2.396694] systemd[1]: Created slice Slice /system/getty.
> [ OK ] Created slice Slice /system/getty.
> [ 2.410476] systemd[1]: Created slice Slice /system/modprobe.
> [ OK ] Created slice Slice /system/modprobe.
> [ 2.424209] systemd[1]: Created slice Slice /system/serial-getty.
> [ OK ] Created slice Slice /system/serial-getty.
> [ 2.438389] systemd[1]: Created slice User and Session Slice.
> [ OK ] Created slice User and Session Slice.
> [ 2.450954] systemd[1]: Started Dispatch Password Requests to Console
> Directory Watch.
> [ OK ] Started Dispatch Password …ts to Console Directory Watch.
> [ 2.467638] systemd[1]: Started Forward Password Requests to Wall
> Directory Watch.
> [ OK ] Started Forward Password R…uests to Wall Directory Watch.
> [ 2.484011] systemd[1]: Reached target Path Units.
> [ OK ] Reached target Path Units.
> [ 2.494464] systemd[1]: Reached target Remote File Systems.
> [ OK ] Reached target Remote File Systems.
> [ 2.506485] systemd[1]: Reached target Slice Units.
> [ OK ] Reached target Slice Units.
> [ 2.517119] systemd[1]: Reached target Swaps.
> [ OK ] Reached target Swaps.
> [ 2.586411] systemd[1]: Listening on RPCbind Server Activation Socket.
> [ OK ] Listening on RPCbind Server Activation Socket.
> [ 2.600701] systemd[1]: Reached target RPC Port Mapper.
> [ OK ] Reached target RPC Port Mapper.
> [ 2.612616] systemd[1]: Listening on Syslog Socket.
> [ OK ] Listening on Syslog Socket.
> [ 2.623452] systemd[1]: Listening on initctl Compatibility Named Pipe.
> [ OK ] Listening on initctl Compatibility Named Pipe.
> [ 2.637954] systemd[1]: Listening on Journal Audit Socket.
> [ OK ] Listening on Journal Audit Socket.
> [ 2.650037] systemd[1]: Listening on Journal Socket (/dev/log).
> [ OK ] Listening on Journal Socket (/dev/log).
> [ 2.663102] systemd[1]: Listening on Journal Socket.
> [ OK ] Listening on Journal Socket.
> [ 2.674363] systemd[1]: Listening on Network Service Netlink Socket.
> [ OK ] Listening on Network Service Netlink Socket.
> [ 2.688327] systemd[1]: Listening on udev Control Socket.
> [ OK ] Listening on udev Control Socket.
> [ 2.700193] systemd[1]: Listening on udev Kernel Socket.
> [ OK ] Listening on udev Kernel Socket.
> [ 2.711963] systemd[1]: Listening on User Database Manager Socket.
> [ OK ] Listening on User Database Manager Socket.
> [ 2.749696] systemd[1]: Mounting Huge Pages File System...
> Mounting Huge Pages File System...
> [ 2.764346] systemd[1]: Mounting POSIX Message Queue File System...
> Mounting POSIX Message Queue File System...
> [ 2.780591] systemd[1]: Mounting Kernel Debug File System...
> Mounting Kernel Debug File System...
> [ 2.792560] systemd[1]: Kernel Trace File System was skipped because
> of a failed condition check (ConditionPathExists=/sys/kernel/tracing).
> [ 2.805768] systemd[1]: Create List of Static Device Nodes was
> skipped because of a failed condition check
> (ConditionFileNotEmpty=/lib/modules/6.9.0-rc1-00004-gcb630dd69df3/modules.devname).
> [ 2.826957] systemd[1]: Starting Load Kernel Module configfs...
> Starting Load Kernel Module configfs...
> [ 2.842860] systemd[1]: Starting Load Kernel Module drm...
> Starting Load Kernel Module drm...
> [ 2.857874] systemd[1]: Starting Load Kernel Module fuse...
> Starting Load Kernel Module fuse...
> [ 2.879679] systemd[1]: Starting RPC Bind...
> Starting RPC Bind...
> [ 2.888514] systemd[1]: File System Check on Root Device was skipped
> because of a failed condition check (ConditionPathIsReadWrite=!/).
> [ 2.907067] systemd[1]: Starting Journal Service...
> Starting Journal Service...
> [ 2.925119] systemd[1]: Starting Load Kernel Modules...
> Starting Load Kernel Modules...
> [ 2.940298] systemd[1]: Starting Generate network units from Kernel
> command line...
> Starting Generate network …ts from Kernel command line...
> [ 2.959955] systemd[1]: Starting Remount Root and Kernel File Systems...
> Starting Remount Root and Kernel File Systems...
> [ 2.977958] systemd[1]: Starting Coldplug All udev Devices...
> Starting Coldplug All udev Devices...
> [ 2.995944] systemd[1]: Started RPC Bind.
> [ OK ] Started RPC Bind.
> [ 3.005902] systemd[1]: Mounted Huge Pages File System.
> [ OK ] Mounted Huge Pages File System.
> [ 3.018033] systemd[1]: Mounted POSIX Message Queue File System.
> [ OK ] Mounted POSIX Message Queue File System.[ 3.029658] EXT4-fs
> (mmcblk0p2): re-mounted 52830f5f-ab50-4125-a606-3c65100b7d4a r/w. Quota
> mode: none.
>
> [ 3.043175] systemd[1]: Started Journal Service.
> [ OK ] Started Journal Service.
> [ OK ] Mounted Kernel Debug File System.
> [ OK ] Finished Load Kernel Module configfs.
> [ OK ] Finished Load Kernel Module drm.
> [ OK ] Finished Load Kernel Module fuse.
> [FAILED] Failed to start Load Kernel Modules.
> See 'systemctl status systemd-modules-load.service' for details.
> [ OK ] Finished Generate network units from Kernel command line.
> [ OK ] Finished Remount Root and Kernel File Systems.
> Mounting Kernel Configuration File System...
> Starting Flush Journal to Persistent Storage...
> Starting Apply Kernel Variables...
> Starting Create Static Device Nodes in /dev...[ 3.206617]
> systemd-journald[124]: Received client request to flush runtime journal.
>
> [ OK ] Mounted Kernel Configuration File System.
> [ OK ] Finished Flush Journal to Persistent Storage.
> [ OK ] Finished Apply Kernel Variables.
> [ OK ] Finished Create Static Device Nodes in /dev.
> [ OK ] Reached target Preparation for Local File Systems.
> Mounting /tmp...
> Mounting /var/volatile...
> [ 3.338366] audit: type=1334 audit(1651167746.684:2): prog-id=5 op=LOAD
> [ 3.345166] audit: type=1334 audit(1651167746.688:3): prog-id=6 op=LOAD
> Starting Rule-based Manage…for Device Events and Files...
> [ OK ] Mounted /tmp.
> [ OK ] Mounted /var/volatile.
> Mounting /var/volatile/tmp...
> Starting Load/Save Random Seed...
> [ OK ] Mounted /var/volatile/tmp.
> [ OK ] Reached target Local File Systems.
> Starting Create Volatile Files and Directories...
> [ OK ] Finished Create Volatile Files and Directories.
> Starting Network Time Synchronization...
> Starting Record System Boot/Shutdown in UTMP...
> [ OK ] Started Rule-based Manager for Device Events and Files.
> [ OK ] Finished Coldplug All udev Devices.
> [ OK ] Finished Record System Boot/Shutdown in UTMP.
> [ OK ] Started Network Time Synchronization.
> [ OK ] Reached target System Initialization.
> [ OK ] Started Daily Cleanup of Temporary Directories.
> [ OK ] Reached target System Time Set.
> [ OK ] Started Daily rotation of log files.
> [ OK ] Reached target Timer Units.
> [ OK ] Listening on D-Bus System Message Bus Socket.
> Starting sshd.socket...
> [ OK ] Listening on sshd.socket.
> [ OK ] Reached target Socket Units.
> [ OK ] Reached target Basic System.
> [ OK ] Started Job spooling tools.
> [ OK ] Started Periodic Command Scheduler.
> Starting D-Bus System Message Bus...
> Starting IPv6 Packet Filtering Framework...
> Starting IPv4 Packet Filtering Framework...
> [ OK ] Started irqbalance daemon.
> [ OK ] Started Hardware RNG Entropy Gatherer Daemon.
> [ OK ] Started System Logging Service.
> Starting Resets System Activity Logs...
> [ 4.124453] audit: type=1334 audit(1651254541.860:4): prog-id=7 op=LOAD
> [ 4.131266] audit: type=1334 audit(1651254541.868:5): prog-id=8 op=LOAD
> Starting User Login Management...
> Starting OpenSSH Key Generation...
> [ OK ] Finished IPv6 Packet Filtering Framework.
> [ OK ] Finished IPv4 Packet Filtering Framework.
> [ OK ] Reached target Preparation for Network.
> Starting Network Configuration...
> [ OK ] Finished Resets System Activity Logs.
> [ OK ] Finished OpenSSH Key Generation.
> [ OK ] Started Network Configuration.
> Starting Network Name Resolution...
> [ OK ] Started Network Name Resolution.
> [ OK ] Reached target Network.
> [ OK ] Reached target Host and Network Name Lookups.
> [ OK ] Started Netperf Benchmark Server.
> [ OK ] Started NFS status monitor for NFSv2/3 locking..
> [ OK ] Started Respond to IPv6 Node Information Queries.
> [ OK ] Started Network Router Discovery Daemon.
> Starting Permit User Sessions...
> [ OK ] Started Xinetd A Powerful Replacement For Inetd.
> [ OK ] Finished Permit User Sessions.
> [ OK ] Started Getty on tty1.
> [ OK ] Started Serial Getty on ttyLF0.
> [ OK ] Reached target Login Prompts.
> [ OK ] Created slice Slice /system/systemd-fsck.
> [ OK ] Found device /dev/mmcblk0p1.
> Starting File System Check on /dev/mmcblk0p1...
> [ OK ] Finished File System Check on /dev/mmcblk0p1.
> Mounting /run/media/boot_s32g3-mmcblk0p1...
> [ OK ] Mounted /run/media/boot_s32g3-mmcblk0p1.
> [ OK ] Finished Load/Save Random Seed.
> [ OK ] Started D-Bus System Message Bus.
> [ OK ] Started User Login Management.
> [ OK ] Reached target Multi-User System.
> Starting Record Runlevel Change in UTMP...
> [ OK ] Finished Record Runlevel Change in UTMP.
>
>
> Regards,
> Ghennadi
>
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: leds: add LED_FUNCTION_MOBILE for mobile network
From: Rob Herring @ 2024-03-25 13:26 UTC (permalink / raw)
To: INAGAKI Hiroshi
Cc: lee, krzysztof.kozlowski+dt, devicetree, Hauke Mehrtens, pavel,
conor+dt, linux-kernel, linux-leds
In-Reply-To: <20240323074326.1428-2-musashino.open@gmail.com>
On Sat, 23 Mar 2024 16:36:09 +0900, INAGAKI Hiroshi wrote:
> Add LED_FUNCTION_MOBILE for LEDs that indicate status of mobile network
> connection. This is useful to distinguish those LEDs from LEDs that
> indicates status of wired "wan" connection.
>
> example (on stock fw):
>
> IIJ SA-W2 has "Mobile" LEDs that indicate status (no signal, too low,
> low, good) of mobile network connection via dongle connected to USB
> port.
>
> - no signal: (none, turned off)
> - too low: green:mobile & red:mobile (amber, blink)
> - low: green:mobile & red:mobile (amber, turned on)
> - good: green:mobile (turned on)
>
> Suggested-by: Hauke Mehrtens <hauke@hauke-m.de>
> Signed-off-by: INAGAKI Hiroshi <musashino.open@gmail.com>
> ---
> v1 -> v2
>
> - move _MOBILE before _MTD
> - improve the commit description
>
> include/dt-bindings/leds/common.h | 1 +
> 1 file changed, 1 insertion(+)
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH net-next v2 0/9] Add support for OPEN Alliance 10BASE-T1x MACPHY Serial Interface
From: Parthiban.Veerasooran @ 2024-03-25 13:24 UTC (permalink / raw)
To: benjamin
Cc: netdev, devicetree, linux-kernel, linux-doc, Horatiu.Vultur,
Woojung.Huh, Nicolas.Ferre, UNGLinuxDriver, Thorsten.Kummermehr,
davem, edumazet, kuba, pabeni, robh+dt, krzysztof.kozlowski+dt,
conor+dt, corbet, Steen.Hegelund, rdunlap, horms, casper.casan,
andrew
In-Reply-To: <ea86159bb555336ae21311770e3a1a6374092e64.camel@bigler.one>
Hi Benjamin Bigler,
Thank you for your testing and feedback. It would be really helpful to
bring the driver to a good shape. We really appreciate your efforts on this.
On 24/03/24 5:25 pm, Benjamin Bigler wrote:
> [Some people who received this message don't often get email from benjamin@bigler.one. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> Hi Parthiban
>
> I hope I send this in the right context as it is not related to just one patch or
> some specific code.
>
> I conducted UDP load testing using three i.MX8MM boards in conjunction with the
> LAN8651. The setup involved one board functioning as a server, which is just
> echoing back received data, while the remaining two boards acted as clients,
> sending UDP packets of different sizes in various bursts to the server.
> Due to hardware constraints, the SPI bus speed was limited to 15 MHz, which might
> have influenced the results.
>
> During the tests I experienced some issues:
>
> - The boards just start receiving after first sending something (ping another board).
> Some measurements showed that the irq stays asserted after init. This makes sense
> as far as I understand the chapter 7.7 of the specification, the irq is deasserted
> on reception of the first data header following CSn being asserted. As a workaround
> I trigger the thread at the end of oa_tc6_init.
It looks like the IRQ is asserted on RESET completion and expects a data
chunk from host to deassert the IRQ. I used to test the driver in RPI 4
using iperf3. For some reason I never faced this issue, may be when the
network device is being registered there might be some packet
transmission which leads to deliver a data chunk so that the IRQ is
deasserted. Thanks for the workaround. I think that would be the
solution to solve this issue. Adding the below lines in the end of the
function oa_tc6_init() will trigger the oa_tc6_spi_thread_handler() to
perform an empty data chunk transfer which will deassert the IRQ before
starting the actual data transfer.
/* oa_tc6_sw_reset_macphy() function resets and clears the MAC-PHY reset
* complete status. IRQ is also asserted on reset completion and it is
* remain asserted until MAC-PHY receives a data chunk. So performing an
* empty data chunk transmission will deassert the IRQ. Refer section
* 7.7 and 9.2.8.8 in the OPEN Alliance specification for more details.
*/
tc6->int_flag = true;
wake_up_interruptible(&tc6->spi_wq);
>
> - If there is a lot of traffic, the receive buffer overflow error spams the log.
>
> - If there is a lot of traffic, I got various kernel panics in oa_tc6_update_rx_skb.
> Mostly because more data to rx_skb is added than allocated and sometimes because
> rx_skb is null in oa_tc6_update_rx_skb or oa_tc6_prcs_rx_frame_end. Some debugging
> with a logic analyzer showed that the chip is not behave correctly. There is more
> bytes between start_valid and end_valid than there should be. Also there
> seems to be 2 end_valid without a start_valid between. What is common is that the incorrect
> frame starts in a chunk where end_valid and start_valid is set.
> In my opinion its a problem in the chip (maybe related to the errata in the next point)
> but the driver should be resilent and just drop the packet and not cause a kernel panic.
Usually I run into this issue "receive buffer overflow" when I run RPI 4
with default cpu governor setting which is "ondemand". In this case,
even though if I set SPI clock speed as 15 MHz the RPI 4 core clock is
clocking down when it is idle which leads delivering half of the
configured SPI clock speed around 5.9 MHz. So the systems like RPI 4
need performance mode enabled to get the proper clock speed for SPI.
Refer below link for more details.
https://github.com/raspberrypi/linux/issues/3381#issuecomment-1144723750
I used to enable performance mode using the below command.
echo performance | sudo tee
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor > /dev/null
So please ensure the SPI clock speed using a logic analyzer to get the
maximum throughput without receive buffer overflow.
Of course, I agree that the driver should not crash in case of receive
buffer overflow. By referring your investigations, I understand that the
buffers in the MAC-PHY is being continuously overwritten again and again
as the host is very slow to read the data from the MAC-PHY buffers
through SPI which alters the descriptors. There might be two reasons why
we run into this situation.
1. The host is busy doing something else and delays to initiate SPI even
though SPI clock speed is 15 MHz.
2. The SPI clock speed is less than 15 MHz.
I use the below iperf3 setup for my testing and never faced the driver
crash issue even though faced "receive buffer overflow" error when I run
RPI 4 with "ondemand" default mode.
Node 0 - Raspberry Pi 4 with LAN8650 MAC-PHY
$ iperf3 -s
Node 1 - Raspberry Pi 4 with EVB-LAN8670-USB USB Stick
$ iperf3 -c 192.168.5.100 -u -b 10M -i 1 -t 0
and vice versa.
I never faced "receive buffer overflow" error when I run RPI 4 with
"performance" mode enabled and even though all the cores are stressed
using the below command,
$ yes >/dev/null & yes >/dev/null & yes >/dev/null & yes >/dev/null &
Can you share more details about your testing setup and applications you
use, so that I will try to reproduce the issue in my setup to debug the
driver?
>
> - Sometimes the chip stops working. It always asserts the irq but there is no data (rca=0)
> and also exst is not active. I found out that there is an errata (DS80001075) point s3
> that explains this. I set the ZARFE bit in CONFIG0. This also fixes the point above.
> The driver now works since about 2.5 weeks with various load with just one loss of frame
> error where I had to reboot the system after about 4 days.
It is good to hear that the driver works fine with the above changes. As
mentioned in the errata, this continuous interrupt issue is a known
issue with LAN8651 Rev.B0. Switching to LAN8651 Rev.B1 will solve this
issue and no need of any workaround. Setting ZARFE bit in the CONFIG0
will solve the continuous interrupt issue but don't know how the above
"receive buffer overflow" issue also solved. I think it is a good idea
to test with LAN8651 Rev.B1 without setting ZARFE bit once. It would be
interesting to see the result. I am always using LAN8651 Rev.B1 for my
testing.
I should be able to reproduce the "receive buffer overflow" issue and
consequently kernel crash in my setup with LAN8651 Rev.B1 so that I can
investigate the issue further. As I am not able to reproduce in my RPI
4, I need your support for the tests and applications you used in your
setup.
>
> Is there a reason why you removed the netdev watchdog which was active in v2?
When the timeout occurs, there is no further action except increasing
tx_errors. Not seeing this except USB-to-Ethernet which can be removed
unexpectedly. But this is SPI interface which will not be removed
unexpectedly as it is a platform device. That's why we removed this.
Best regards,
Parthiban V
>
> Thanks,
> Benjamin Bigler
>
^ permalink raw reply
* Re: [PATCH v16 7/9] usb: dwc3: qcom: Refactor IRQ handling in glue driver
From: Johan Hovold @ 2024-03-25 13:23 UTC (permalink / raw)
To: Krishna Kurapati PSSNV
Cc: Krzysztof Kozlowski, Rob Herring, Bjorn Andersson, Wesley Cheng,
Konrad Dybcio, Greg Kroah-Hartman, Conor Dooley, Thinh Nguyen,
Felipe Balbi, devicetree, linux-arm-msm, linux-usb, linux-kernel,
quic_ppratap, quic_jackp
In-Reply-To: <50926b91-3c61-4dbf-85c9-7558ab96e628@quicinc.com>
On Mon, Mar 25, 2024 at 06:45:07PM +0530, Krishna Kurapati PSSNV wrote:
> >> +static int dwc3_qcom_setup_irq(struct platform_device *pdev)
> >> +{
> >> + struct dwc3_qcom *qcom = platform_get_drvdata(pdev);
> >> + bool is_multiport;
> >> + int ret;
> >> + int i;
> >> +
> >> + qcom->num_ports = dwc3_qcom_find_num_ports(pdev);
> >> + if (qcom->num_ports < 0)
> >> + return -ENOMEM;
> >
> > Just return 'ret' directly.
>
> Sure, will init ret to -ENOMEM and return ret here.
I meant that you should return whatever error dwc3_qcom_find_num_ports()
returns, so perhaps something like:
ret = dwc3_qcom_find_num_ports(pdev);
if (ret < 0)
return ret;
qcom->num_ports = ret;
It looks like dwc3_qcom_find_num_ports() can also return 0 (e.g. on
malformed DT), which also needs to be handled somehow. I missed that
earlier.
Johan
^ permalink raw reply
* Re: [PATCH v5 2/4] dt-bindings: media: add Maxim MAX96714 GMSL2 Deserializer
From: Julien Massot @ 2024-03-25 13:22 UTC (permalink / raw)
To: Conor Dooley
Cc: linux-media, devicetree, kernel, linux-kernel, mchehab, robh+dt,
krzysztof.kozlowski+dt, conor+dt, sakari.ailus
In-Reply-To: <20240317-petty-backache-b10d0fde62cf@spud>
Hi Conor,
Thanks for your review.
On 3/17/24 16:18, Conor Dooley wrote:
> On Wed, Mar 13, 2024 at 10:49:20AM +0100, Julien Massot wrote:
>> Add DT bindings for Maxim MAX96714 GMSL2 Deserializer.
>>
>> Signed-off-by: Julien Massot <julien.massot@collabora.com>
>> ---
>> Change since v4:
>> - Add compatible for MAX96714 and use it as a fallback for MAX96714F
>> - Remove extra '|' for decriptions
>> - Reference 'i2c-gate' instead of 'i2c-controller'
>>
>> Change since v3:
>> - Renamed file to maxim,max96714.yaml dropped the 'f' suffix
>> - Removed mention to C-PHY since it's not supported by MAX96714 deserializers
>> - Removed bus-type requirement on CSI endpoint since the device only support D-PHY
>> - Removed the clock-lanes property in the dt example
>>
>> Change since v2:
>> - remove reg description
>> - rename enable gpio to powerdown
>> - use generic node name: i2c, serializer, deserializer
>> ---
>> .../bindings/media/i2c/maxim,max96714.yaml | 176 ++++++++++++++++++
>> 1 file changed, 176 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
>> new file mode 100644
>> index 000000000000..59b116092834
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
>> @@ -0,0 +1,176 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2024 Collabora Ltd.
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/media/i2c/maxim,max96714.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Maxim MAX96714 GMSL2 to CSI-2 Deserializer
>> +
>> +maintainers:
>> + - Julien Massot <julien.massot@collabora.com>
>> +
>> +description:
>> + The MAX96714 deserializer converts GMSL2 serial inputs into MIPI
>> + CSI-2 D-PHY formatted output. The device allows the GMSL2 link to
>> + simultaneously transmit bidirectional control-channel data while forward
>> + video transmissions are in progress. The MAX96714 can connect to one
>> + remotely located serializer using industry-standard coax or STP
>> + interconnects. The device cans operate in pixel or tunnel mode. In pixel mode
>> + the MAX96714 can select individual video stream, while the tunnel mode forward all
>> + the MIPI data received by the serializer.
>> +
>> + The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
>> + forward direction and 187.5Mbps in the reverse direction.
>> + MAX96714F only supports a fixed rate of 3Gbps in the forward direction.
>> +
>> +properties:
>> + compatible:
>> + oneOf:
>> + - enum:
>> + - maxim,max96714
>
> There's only once device here, make it const rather than enum.
Okay fixed in v6
>
>> + - items:
>> + - enum:
>> + - maxim,max96714f
>> + - const: maxim,max96714 # fallback for 'f' variant
>
> Drop the comment btw, it doesn't make sense given you have an enum that
> will allow for more devices and it being a fallback is obvious. That
> said, given what you told me on the last version
> | Yes there are a few differences visible to the software, for example the
> | GMSL
> | link rate since MAX96714 support 6 and 3 Gbps, while MAX96714F only
> | supports 3Gbps.
> | the registers map is the same, but a few values are not possible with
> | the 'f' version.
> I don't think your ordering here is correct. The 96714 should fall back
> to the 96714f, not the opposite that you have here, as the f is the
> version which supports fewer features.
>
> I think this should be:
>
> oneOf:
> - const: maxim,max96714f
> - items:
> - enum:
> - maxim,max96714
> - const: maxim,max96714f
I just sent a v6 version with your suggestion. Indeed it makes more sense
to use max96714/7f as a fallback for the non f variant.
Best regards,
Julien
^ permalink raw reply
* Re: [PATCH v4 3/4] dt-bindings: mmc: fsl-imx-esdhc: add NXP S32G3 support
From: Ulf Hansson @ 2024-03-25 13:19 UTC (permalink / raw)
To: Wadim Mueller
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
NXP Linux Team, Greg Kroah-Hartman, Jiri Slaby, Chester Lin,
Andreas Färber, Matthias Brugger, NXP S32 Linux Team,
Tim Harvey, Alexander Stein, Gregor Herburger, Marek Vasut,
Marco Felsch, Hugo Villeneuve, Markus Niebel, Matthias Schiffer,
Stefan Wahren, Bjorn Helgaas, Yannic Moog, Li Yang, devicetree,
linux-kernel, linux-mmc, linux-arm-kernel, linux-serial
In-Reply-To: <20240324214329.29988-4-wafgo01@gmail.com>
On Sun, 24 Mar 2024 at 22:44, Wadim Mueller <wafgo01@gmail.com> wrote:
>
> Add a compatible string for the SDHC binding of NXP S32G3 platforms. Here
> we use "nxp,s32g2-usdhc" as fallback since the s32g2-usdhc
> driver works also on S32G3 platforms.
>
> Signed-off-by: Wadim Mueller <wafgo01@gmail.com>
Applied for next, thanks!
Kind regards
Uffe
> ---
> Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> index 82eb7a24c857..466e7157308a 100644
> --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml
> @@ -90,6 +90,9 @@ properties:
> - enum:
> - fsl,imxrt1170-usdhc
> - const: fsl,imxrt1050-usdhc
> + - items:
> + - const: nxp,s32g3-usdhc
> + - const: nxp,s32g2-usdhc
>
> reg:
> maxItems: 1
> --
> 2.25.1
>
^ permalink raw reply
* [PATCH v6 4/4] media: i2c: add MAX96714 driver
From: Julien Massot @ 2024-03-25 13:16 UTC (permalink / raw)
To: linux-media
Cc: devicetree, kernel, linux-kernel, mchehab, robh+dt,
krzysztof.kozlowski+dt, conor+dt, sakari.ailus, Julien Massot
In-Reply-To: <20240325131634.165361-1-julien.massot@collabora.com>
This driver handles the MAX96714 deserializer in tunnel mode.
The CSI output will replicate all the CSI traffic forwarded by
the remote serializer.
The MAX96714 driver can handle MAX96714 and MAX96714F variants
with the same "maxim,max96714f" compatible.
Signed-off-by: Julien Massot <julien.massot@collabora.com>
---
Change since v5:
- set the driver compatible back to MAX96714F that can be used as a fallback for MAX96714
Change since v4:
- make the driver compatible with MAX96714 instead of MAX96714F
- Add the device id for the MAX96714
Change since v3:
- Maintainers: align to the new binding path
- Kconfig: better describe the symbol
- Aligned the macro
- Store the v4l2_mbus_config_mipi_csi2 structure instead of the full endpoint in the driver private structure
- moved ret variables declaration at last
- Removed extra new lines
- Return the v4l2_subdev_set_routing_with_fmt result in _max96714_set_routing
- Use v4l2_subdev_s_stream_helper instead of the custom max96714_s_stream function
- Removed unnecessary check 'if (priv->tx_link_freq < 0)' in create_subdev since dt is already validated in max96714_parse_dt_txport
- Use div_u64 to fix compilation on 32 bits platforms
- Specify D-PHY for fwnode endpoint parsing since the MAX96714 only supports D-PHY
- Simplify parse_dt function by parsing first the tx_port so that we no longer have to call fwnode_handle_put(priv->rxport.source.ep_fwnode);
- Do not initialize regmap twice
- Use unsigned int instead of u8
Change since v2:
- Use CCI helpers instead of recoding register access
- add missing bitfield header
- Add pattern generator so the deserializer can be tested without a serializer/sensor
---
MAINTAINERS | 7 +
drivers/media/i2c/Kconfig | 14 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/max96714.c | 1029 ++++++++++++++++++++++++++++++++++
4 files changed, 1051 insertions(+)
create mode 100644 drivers/media/i2c/max96714.c
diff --git a/MAINTAINERS b/MAINTAINERS
index c43088157f6d..6423782f04b6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13277,6 +13277,13 @@ S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
F: drivers/staging/media/max96712/max96712.c
+MAX96714 GMSL2 DESERIALIZER DRIVER
+M: Julien Massot <julien.massot@collabora.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
+F: drivers/media/i2c/max96714.c
+
MAX96717 GMSL2 SERIALIZER DRIVER
M: Julien Massot <julien.massot@collabora.com>
L: linux-media@vger.kernel.org
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 1a99396edbcf..64fc4c1c1fc1 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -1573,6 +1573,20 @@ config VIDEO_DS90UB960
Device driver for the Texas Instruments DS90UB960
FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer.
+config VIDEO_MAX96714
+ tristate "Maxim MAX96714 GMSL2 deserializer"
+ depends on OF && I2C && VIDEO_DEV
+ select I2C_MUX
+ select GPIOLIB
+ select V4L2_CCI_I2C
+ help
+ Device driver for the Maxim MAX96714 GMSL2 Deserializer.
+ MAX96714 deserializers convert a GMSL2 input to MIPI CSI-2
+ output.
+
+ To compile this driver as a module, choose M here: the
+ module will be called max96714.
+
config VIDEO_MAX96717
tristate "Maxim MAX96717 GMSL2 Serializer support"
depends on OF && I2C && VIDEO_DEV && COMMON_CLK
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 9e007116f929..7c794441eaff 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_VIDEO_LM3646) += lm3646.o
obj-$(CONFIG_VIDEO_M52790) += m52790.o
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
+obj-$(CONFIG_VIDEO_MAX96714) += max96714.o
obj-$(CONFIG_VIDEO_MAX96717) += max96717.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
diff --git a/drivers/media/i2c/max96714.c b/drivers/media/i2c/max96714.c
new file mode 100644
index 000000000000..8192de389220
--- /dev/null
+++ b/drivers/media/i2c/max96714.c
@@ -0,0 +1,1029 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim GMSL2 Deserializer Driver
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/fwnode.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/i2c-mux.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX96714_DEVICE_ID 0xc9
+#define MAX96714F_DEVICE_ID 0xca
+#define MAX96714_NPORTS 2
+#define MAX96714_PAD_SINK 0
+#define MAX96714_PAD_SOURCE 1
+
+/* DEV */
+#define MAX96714_REG13 CCI_REG8(0x0d)
+#define MAX96714_DEV_REV CCI_REG8(0x0e)
+#define MAX96714_DEV_REV_MASK GENMASK(3, 0)
+#define MAX96714_LINK_LOCK CCI_REG8(0x13)
+#define MAX96714_LINK_LOCK_BIT BIT(3)
+#define MAX96714_IO_CHK0 CCI_REG8(0x38)
+#define MAX96714_PATTERN_CLK_FREQ GENMASK(1, 0)
+/* VID_RX */
+#define MAX96714_VIDEO_RX8 CCI_REG8(0x11a)
+#define MAX96714_VID_LOCK BIT(6)
+
+/* VRX_PATGEN_0 */
+#define MAX96714_PATGEN_0 CCI_REG8(0x240)
+#define MAX96714_PATGEN_1 CCI_REG8(0x241)
+#define MAX96714_PATGEN_MODE GENMASK(5, 4)
+#define MAX96714_PATGEN_VS_DLY CCI_REG24(0x242)
+#define MAX96714_PATGEN_VS_HIGH CCI_REG24(0x245)
+#define MAX96714_PATGEN_VS_LOW CCI_REG24(0x248)
+#define MAX96714_PATGEN_V2H CCI_REG24(0x24b)
+#define MAX96714_PATGEN_HS_HIGH CCI_REG16(0x24e)
+#define MAX96714_PATGEN_HS_LOW CCI_REG16(0x250)
+#define MAX96714_PATGEN_HS_CNT CCI_REG16(0x252)
+#define MAX96714_PATGEN_V2D CCI_REG24(0x254)
+#define MAX96714_PATGEN_DE_HIGH CCI_REG16(0x257)
+#define MAX96714_PATGEN_DE_LOW CCI_REG16(0x259)
+#define MAX96714_PATGEN_DE_CNT CCI_REG16(0x25B)
+#define MAX96714_PATGEN_GRAD_INC CCI_REG8(0x25d)
+#define MAX96714_PATGEN_CHKB_COLOR_A CCI_REG24(0x25E)
+#define MAX96714_PATGEN_CHKB_COLOR_B CCI_REG24(0x261)
+#define MAX96714_PATGEN_CHKB_RPT_CNT_A CCI_REG8(0x264)
+#define MAX96714_PATGEN_CHKB_RPT_CNT_B CCI_REG8(0x265)
+#define MAX96714_PATGEN_CHKB_ALT CCI_REG8(0x266)
+/* BACKTOP */
+#define MAX96714_BACKTOP25 CCI_REG8(0x320)
+#define CSI_DPLL_FREQ_MASK GENMASK(4, 0)
+
+/* MIPI_PHY */
+#define MAX96714_MIPI_PHY0 CCI_REG8(0x330)
+#define MAX96714_FORCE_CSI_OUT BIT(7)
+#define MAX96714_MIPI_STDBY_N CCI_REG8(0x332)
+#define MAX96714_MIPI_STDBY_MASK GENMASK(5, 4)
+#define MAX96714_MIPI_LANE_MAP CCI_REG8(0x333)
+#define MAX96714_MIPI_POLARITY CCI_REG8(0x335)
+#define MAX96714_MIPI_POLARITY_MASK GENMASK(5, 0)
+
+/* MIPI_TX */
+#define MAX96714_MIPI_LANE_CNT CCI_REG8(0x44a)
+#define MAX96714_CSI2_LANE_CNT_MASK GENMASK(7, 6)
+#define MAX96714_MIPI_TX52 CCI_REG8(0x474)
+#define MAX96714_TUN_EN BIT(0)
+
+#define MHZ(v) ((u32)((v) * 1000000U))
+
+enum max96714_vpg_mode {
+ MAX96714_VPG_DISABLED = 0,
+ MAX96714_VPG_CHECKERBOARD = 1,
+ MAX96714_VPG_GRADIENT = 2,
+};
+
+struct max96714_rxport {
+ struct {
+ struct v4l2_subdev *sd;
+ u16 pad;
+ struct fwnode_handle *ep_fwnode;
+ } source;
+ struct regulator *poc;
+};
+
+struct max96714_txport {
+ struct v4l2_fwnode_endpoint vep;
+};
+
+struct max96714_priv {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct gpio_desc *pd_gpio;
+ struct max96714_rxport rxport;
+ struct i2c_mux_core *mux;
+ u64 enabled_source_streams;
+ struct v4l2_subdev sd;
+ struct media_pad pads[MAX96714_NPORTS];
+ struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct v4l2_async_notifier notifier;
+ s64 tx_link_freq;
+ enum max96714_vpg_mode pattern;
+};
+
+static inline struct max96714_priv *sd_to_max96714(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct max96714_priv, sd);
+}
+
+static int max96714_enable_tx_port(struct max96714_priv *priv)
+{
+ return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
+ MAX96714_MIPI_STDBY_MASK,
+ MAX96714_MIPI_STDBY_MASK, NULL);
+}
+
+static int max96714_disable_tx_port(struct max96714_priv *priv)
+{
+ return cci_update_bits(priv->regmap, MAX96714_MIPI_STDBY_N,
+ MAX96714_MIPI_STDBY_MASK, 0, NULL);
+}
+
+static bool max96714_tx_port_enabled(struct max96714_priv *priv)
+{
+ u64 val;
+
+ cci_read(priv->regmap, MAX96714_MIPI_STDBY_N, &val, NULL);
+
+ return val & MAX96714_MIPI_STDBY_MASK;
+}
+
+static int max96714_apply_patgen_timing(struct max96714_priv *priv,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_mbus_framefmt *fmt =
+ v4l2_subdev_state_get_format(state, MAX96714_PAD_SOURCE);
+ const u32 h_active = fmt->width;
+ const u32 h_fp = 88;
+ const u32 h_sw = 44;
+ const u32 h_bp = 148;
+ u32 h_tot;
+
+ const u32 v_active = fmt->height;
+ const u32 v_fp = 4;
+ const u32 v_sw = 5;
+ const u32 v_bp = 36;
+ u32 v_tot;
+ int ret = 0;
+
+ h_tot = h_active + h_fp + h_sw + h_bp;
+ v_tot = v_active + v_fp + v_sw + v_bp;
+
+ /* 75 Mhz pixel clock */
+ cci_update_bits(priv->regmap, MAX96714_IO_CHK0,
+ MAX96714_PATTERN_CLK_FREQ, 1, &ret);
+
+ dev_info(&priv->client->dev, "height: %d width: %d\n", fmt->height,
+ fmt->width);
+
+ cci_write(priv->regmap, MAX96714_PATGEN_VS_DLY, 0, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_VS_HIGH, v_sw * h_tot, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_VS_LOW,
+ (v_active + v_fp + v_bp) * h_tot, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_HS_HIGH, h_sw, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_HS_LOW, h_active + h_fp + h_bp,
+ &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_V2D,
+ h_tot * (v_sw + v_bp) + (h_sw + h_bp), &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_HS_CNT, v_tot, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_DE_HIGH, h_active, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_DE_LOW, h_fp + h_sw + h_bp,
+ &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_DE_CNT, v_active, &ret);
+ /* B G R */
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_A, 0xfecc00, &ret);
+ /* B G R */
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_COLOR_B, 0x006aa7, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_A, 0x3c, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_RPT_CNT_B, 0x3c, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_CHKB_ALT, 0x3c, &ret);
+ cci_write(priv->regmap, MAX96714_PATGEN_GRAD_INC, 0x10, &ret);
+
+ return ret;
+}
+
+static int max96714_apply_patgen(struct max96714_priv *priv,
+ struct v4l2_subdev_state *state)
+{
+ unsigned int val;
+ int ret = 0;
+
+ if (priv->pattern)
+ ret = max96714_apply_patgen_timing(priv, state);
+
+ cci_write(priv->regmap, MAX96714_PATGEN_0, priv->pattern ? 0xfb : 0,
+ &ret);
+
+ val = FIELD_PREP(MAX96714_PATGEN_MODE, priv->pattern);
+ cci_update_bits(priv->regmap, MAX96714_PATGEN_1, MAX96714_PATGEN_MODE,
+ val, &ret);
+ return ret;
+}
+
+static int max96714_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct max96714_priv *priv =
+ container_of(ctrl->handler, struct max96714_priv, ctrl_handler);
+ int ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_TEST_PATTERN:
+ priv->pattern = ctrl->val;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ret = cci_update_bits(priv->regmap, MAX96714_MIPI_PHY0,
+ MAX96714_FORCE_CSI_OUT,
+ priv->pattern ? MAX96714_FORCE_CSI_OUT : 0, NULL);
+
+ /* Pattern generator doesn't work with tunnel mode */
+ return cci_update_bits(priv->regmap, MAX96714_MIPI_TX52,
+ MAX96714_TUN_EN,
+ priv->pattern ? 0 : MAX96714_TUN_EN, &ret);
+}
+
+static const char * const max96714_test_pattern[] = {
+ "Disabled",
+ "Checkerboard",
+ "Gradient"
+};
+
+static const struct v4l2_ctrl_ops max96714_ctrl_ops = {
+ .s_ctrl = max96714_s_ctrl,
+};
+
+static int max96714_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 source_pad, u64 streams_mask)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ u64 sink_streams;
+ int ret;
+
+ if (!priv->enabled_source_streams)
+ max96714_enable_tx_port(priv);
+
+ ret = max96714_apply_patgen(priv, state);
+ if (ret)
+ goto err;
+
+ if (!priv->pattern) {
+ if (!priv->rxport.source.sd) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ sink_streams =
+ v4l2_subdev_state_xlate_streams(state,
+ MAX96714_PAD_SOURCE,
+ MAX96714_PAD_SINK,
+ &streams_mask);
+
+ ret = v4l2_subdev_enable_streams(priv->rxport.source.sd,
+ priv->rxport.source.pad,
+ sink_streams);
+ if (ret)
+ goto err;
+ }
+
+ priv->enabled_source_streams |= streams_mask;
+
+ return 0;
+
+err:
+ if (!priv->enabled_source_streams)
+ max96714_disable_tx_port(priv);
+
+ return ret;
+}
+
+static int max96714_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 source_pad, u64 streams_mask)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ u64 sink_streams;
+ int ret;
+
+ if (!priv->pattern && priv->rxport.source.sd) {
+ sink_streams =
+ v4l2_subdev_state_xlate_streams(state,
+ MAX96714_PAD_SOURCE,
+ MAX96714_PAD_SINK,
+ &streams_mask);
+
+ ret = v4l2_subdev_disable_streams(priv->rxport.source.sd,
+ priv->rxport.source.pad,
+ sink_streams);
+ if (ret)
+ return ret;
+ }
+
+ priv->enabled_source_streams &= ~streams_mask;
+
+ if (!priv->enabled_source_streams)
+ max96714_disable_tx_port(priv);
+
+ return 0;
+}
+
+static int max96714_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *format)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
+ priv->enabled_source_streams)
+ return -EBUSY;
+
+ /* No transcoding, source and sink formats must match. */
+ if (format->pad == MAX96714_PAD_SOURCE)
+ return v4l2_subdev_get_fmt(sd, state, format);
+
+ fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = format->format;
+
+ fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+ format->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = format->format;
+
+ return 0;
+}
+
+static int _max96714_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ static const struct v4l2_mbus_framefmt format = {
+ .width = 1280,
+ .height = 1080,
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .field = V4L2_FIELD_NONE,
+ };
+ int ret;
+
+ /*
+ * Note: we can only support up to V4L2_FRAME_DESC_ENTRY_MAX, until
+ * frame desc is made dynamically allocated.
+ */
+ if (routing->num_routes > V4L2_FRAME_DESC_ENTRY_MAX)
+ return -EINVAL;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ return v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+}
+
+static int max96714_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
+ return -EBUSY;
+
+ return _max96714_set_routing(sd, state, which, routing);
+}
+
+static int max96714_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_route routes[] = {
+ {
+ .sink_pad = MAX96714_PAD_SINK,
+ .sink_stream = 0,
+ .source_pad = MAX96714_PAD_SOURCE,
+ .source_stream = 0,
+ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+ }
+ };
+ struct v4l2_subdev_krouting routing = {
+ .num_routes = ARRAY_SIZE(routes),
+ .routes = routes,
+ };
+
+ return _max96714_set_routing(sd, state, V4L2_SUBDEV_FORMAT_ACTIVE,
+ &routing);
+}
+
+static const struct v4l2_subdev_pad_ops max96714_pad_ops = {
+ .enable_streams = max96714_enable_streams,
+ .disable_streams = max96714_disable_streams,
+
+ .set_routing = max96714_set_routing,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = max96714_set_fmt,
+};
+
+static bool max96714_link_locked(struct max96714_priv *priv)
+{
+ u64 val = 0;
+
+ cci_read(priv->regmap, MAX96714_LINK_LOCK, &val, NULL);
+
+ return val & MAX96714_LINK_LOCK_BIT;
+}
+
+static void max96714_link_status(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Link locked:%d\n", max96714_link_locked(priv));
+}
+
+static bool max96714_pipe_locked(struct max96714_priv *priv)
+{
+ u64 val;
+
+ cci_read(priv->regmap, MAX96714_VIDEO_RX8, &val, NULL);
+
+ return val & MAX96714_VID_LOCK;
+}
+
+static void max96714_pipe_status(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Pipe vidlock:%d\n", max96714_pipe_locked(priv));
+}
+
+static void max96714_csi_status(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u64 freq = 0;
+
+ cci_read(priv->regmap, MAX96714_BACKTOP25, &freq, NULL);
+ freq = FIELD_GET(CSI_DPLL_FREQ_MASK, freq);
+
+ dev_info(dev, "CSI controller DPLL freq:%u00MHz CSIPHY enabled:%d\n",
+ (u8)freq, max96714_tx_port_enabled(priv));
+}
+
+static int max96714_log_status(struct v4l2_subdev *sd)
+{
+ struct max96714_priv *priv = sd_to_max96714(sd);
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Deserializer: max96714\n");
+
+ max96714_link_status(priv);
+ max96714_pipe_status(priv);
+ max96714_csi_status(priv);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops max96714_subdev_core_ops = {
+ .log_status = max96714_log_status,
+};
+
+static const struct v4l2_subdev_video_ops max96714_video_ops = {
+ .s_stream = v4l2_subdev_s_stream_helper,
+};
+
+static const struct v4l2_subdev_internal_ops max96714_internal_ops = {
+ .init_state = max96714_init_state,
+};
+
+static const struct v4l2_subdev_ops max96714_subdev_ops = {
+ .video = &max96714_video_ops,
+ .core = &max96714_subdev_core_ops,
+ .pad = &max96714_pad_ops,
+};
+
+static const struct media_entity_operations max96714_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static int max96714_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *subdev,
+ struct v4l2_async_connection *asd)
+{
+ struct max96714_priv *priv = sd_to_max96714(notifier->sd);
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ ret = media_entity_get_fwnode_pad(&subdev->entity,
+ priv->rxport.source.ep_fwnode,
+ MEDIA_PAD_FL_SOURCE);
+ if (ret < 0) {
+ dev_err(dev, "Failed to find pad for %s\n", subdev->name);
+ return ret;
+ }
+
+ priv->rxport.source.sd = subdev;
+ priv->rxport.source.pad = ret;
+
+ ret = media_create_pad_link(&priv->rxport.source.sd->entity,
+ priv->rxport.source.pad, &priv->sd.entity,
+ MAX96714_PAD_SINK,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
+ if (ret) {
+ dev_err(dev, "Unable to link %s:%u -> %s:%u\n",
+ priv->rxport.source.sd->name, priv->rxport.source.pad,
+ priv->sd.name, MAX96714_PAD_SINK);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations max96714_notify_ops = {
+ .bound = max96714_notify_bound,
+};
+
+static int max96714_v4l2_notifier_register(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct max96714_rxport *rxport = &priv->rxport;
+ struct v4l2_async_connection *asd;
+ int ret;
+
+ if (!rxport->source.ep_fwnode)
+ return 0;
+
+ v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
+
+ asd = v4l2_async_nf_add_fwnode(&priv->notifier,
+ rxport->source.ep_fwnode,
+ struct v4l2_async_connection);
+ if (IS_ERR(asd)) {
+ dev_err(dev, "Failed to add subdev: %pe", asd);
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return PTR_ERR(asd);
+ }
+
+ priv->notifier.ops = &max96714_notify_ops;
+
+ ret = v4l2_async_nf_register(&priv->notifier);
+ if (ret) {
+ dev_err(dev, "Failed to register subdev_notifier");
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void max96714_v4l2_notifier_unregister(struct max96714_priv *priv)
+{
+ v4l2_async_nf_unregister(&priv->notifier);
+ v4l2_async_nf_cleanup(&priv->notifier);
+}
+
+static int max96714_create_subdev(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96714_subdev_ops);
+ priv->sd.internal_ops = &max96714_internal_ops;
+
+ v4l2_ctrl_handler_init(&priv->ctrl_handler, 1);
+ priv->sd.ctrl_handler = &priv->ctrl_handler;
+
+ v4l2_ctrl_new_int_menu(&priv->ctrl_handler, NULL, V4L2_CID_LINK_FREQ,
+ 0, 0, &priv->tx_link_freq);
+ if (priv->ctrl_handler.error) {
+ ret = priv->ctrl_handler.error;
+ goto err_free_ctrl;
+ }
+
+ v4l2_ctrl_new_std_menu_items(&priv->ctrl_handler,
+ &max96714_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(max96714_test_pattern) - 1,
+ 0, 0, max96714_test_pattern);
+ if (priv->ctrl_handler.error) {
+ ret = priv->ctrl_handler.error;
+ goto err_free_ctrl;
+ }
+
+ priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+ priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+ priv->sd.entity.ops = &max96714_entity_ops;
+
+ priv->pads[MAX96714_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ priv->pads[MAX96714_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&priv->sd.entity,
+ MAX96714_NPORTS,
+ priv->pads);
+ if (ret)
+ goto err_free_ctrl;
+
+ priv->sd.state_lock = priv->sd.ctrl_handler->lock;
+
+ ret = v4l2_subdev_init_finalize(&priv->sd);
+ if (ret)
+ goto err_entity_cleanup;
+
+ ret = max96714_v4l2_notifier_register(priv);
+ if (ret) {
+ dev_err(dev, "v4l2 subdev notifier register failed: %d\n", ret);
+ goto err_subdev_cleanup;
+ }
+
+ ret = v4l2_async_register_subdev(&priv->sd);
+ if (ret) {
+ dev_err(dev, "v4l2_async_register_subdev error: %d\n", ret);
+ goto err_unreg_notif;
+ }
+
+ return 0;
+
+err_unreg_notif:
+ max96714_v4l2_notifier_unregister(priv);
+err_subdev_cleanup:
+ v4l2_subdev_cleanup(&priv->sd);
+err_entity_cleanup:
+ media_entity_cleanup(&priv->sd.entity);
+err_free_ctrl:
+ v4l2_ctrl_handler_free(&priv->ctrl_handler);
+
+ return ret;
+};
+
+static void max96714_destroy_subdev(struct max96714_priv *priv)
+{
+ max96714_v4l2_notifier_unregister(priv);
+ v4l2_async_unregister_subdev(&priv->sd);
+
+ v4l2_subdev_cleanup(&priv->sd);
+
+ media_entity_cleanup(&priv->sd.entity);
+ v4l2_ctrl_handler_free(&priv->ctrl_handler);
+}
+
+static int max96714_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
+{
+ return 0;
+}
+
+static int max96714_i2c_mux_init(struct max96714_priv *priv)
+{
+ priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
+ 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
+ max96714_i2c_mux_select, NULL);
+ if (!priv->mux)
+ return -ENOMEM;
+
+ return i2c_mux_add_adapter(priv->mux, 0, 0, 0);
+}
+
+static int max96714_init_tx_port(struct max96714_priv *priv)
+{
+ struct v4l2_mbus_config_mipi_csi2 *mipi;
+ unsigned long lanes_used = 0;
+ unsigned int val, lane;
+ int ret;
+
+ ret = max96714_disable_tx_port(priv);
+
+ mipi = &priv->mipi_csi2;
+ val = div_u64(priv->tx_link_freq * 2, MHZ(100));
+
+ cci_update_bits(priv->regmap, MAX96714_BACKTOP25,
+ CSI_DPLL_FREQ_MASK, val, &ret);
+
+ val = FIELD_PREP(MAX96714_CSI2_LANE_CNT_MASK, mipi->num_data_lanes - 1);
+ cci_update_bits(priv->regmap, MAX96714_MIPI_LANE_CNT,
+ MAX96714_CSI2_LANE_CNT_MASK, val, &ret);
+
+ /* lanes polarity */
+ val = 0;
+ for (lane = 0; lane < mipi->num_data_lanes + 1; lane++) {
+ if (!mipi->lane_polarities[lane])
+ continue;
+ if (lane == 0)
+ /* clock lane */
+ val |= BIT(5);
+ else if (lane < 3)
+ /* Lane D0 and D1 */
+ val |= BIT(lane - 1);
+ else
+ /* D2 and D3 */
+ val |= BIT(lane);
+ }
+
+ cci_update_bits(priv->regmap, MAX96714_MIPI_POLARITY,
+ MAX96714_MIPI_POLARITY_MASK, val, &ret);
+
+ /* lanes mapping */
+ val = 0;
+ for (lane = 0; lane < mipi->num_data_lanes; lane++) {
+ val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
+ lanes_used |= BIT(mipi->data_lanes[lane] - 1);
+ }
+
+ /* Unused lanes need to be mapped as well to not have
+ * the same lanes mapped twice.
+ */
+ for (; lane < 4; lane++) {
+ unsigned int idx = find_first_zero_bit(&lanes_used, 4);
+
+ val |= idx << (lane * 2);
+ lanes_used |= BIT(idx);
+ }
+
+ return cci_write(priv->regmap, MAX96714_MIPI_LANE_MAP, val, &ret);
+}
+
+static int max96714_rxport_enable_poc(struct max96714_priv *priv)
+{
+ struct max96714_rxport *rxport = &priv->rxport;
+
+ if (!rxport->poc)
+ return 0;
+
+ return regulator_enable(rxport->poc);
+}
+
+static int max96714_rxport_disable_poc(struct max96714_priv *priv)
+{
+ struct max96714_rxport *rxport = &priv->rxport;
+
+ if (!rxport->poc)
+ return 0;
+
+ return regulator_disable(rxport->poc);
+}
+
+static int max96714_parse_dt_txport(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct v4l2_fwnode_endpoint vep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct fwnode_handle *ep_fwnode;
+ u32 num_data_lanes;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96714_PAD_SOURCE, 0, 0);
+ if (!ep_fwnode)
+ return -EINVAL;
+
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep_fwnode, &vep);
+ fwnode_handle_put(ep_fwnode);
+ if (ret) {
+ dev_err(dev, "tx: failed to parse endpoint data\n");
+ return -EINVAL;
+ }
+
+ if (vep.nr_of_link_frequencies != 1) {
+ ret = -EINVAL;
+ goto err_free_vep;
+ }
+
+ priv->tx_link_freq = vep.link_frequencies[0];
+ /* Min 50MHz, Max 1250MHz, 50MHz step */
+ if (priv->tx_link_freq < MHZ(50) || priv->tx_link_freq > MHZ(1250) ||
+ (u32)priv->tx_link_freq % MHZ(50)) {
+ dev_err(dev, "tx: invalid link frequency\n");
+ ret = -EINVAL;
+ goto err_free_vep;
+ }
+
+ num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
+ if (num_data_lanes < 1 || num_data_lanes > 4) {
+ dev_err(dev,
+ "tx: invalid number of data lanes must be 1 to 4\n");
+ ret = -EINVAL;
+ goto err_free_vep;
+ }
+
+ memcpy(&priv->mipi_csi2, &vep.bus.mipi_csi2, sizeof(priv->mipi_csi2));
+
+err_free_vep:
+ v4l2_fwnode_endpoint_free(&vep);
+
+ return ret;
+};
+
+static int max96714_parse_dt_rxport(struct max96714_priv *priv)
+{
+ static const char *poc_name = "port0-poc";
+ struct max96714_rxport *rxport = &priv->rxport;
+ struct device *dev = &priv->client->dev;
+ struct fwnode_handle *ep_fwnode;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96714_PAD_SINK, 0, 0);
+ if (!ep_fwnode)
+ return -ENOENT;
+
+ rxport->source.ep_fwnode = fwnode_graph_get_remote_endpoint(ep_fwnode);
+ fwnode_handle_put(ep_fwnode);
+
+ if (!rxport->source.ep_fwnode) {
+ dev_err(dev, "rx: no remote endpoint\n");
+ return -EINVAL;
+ }
+
+ rxport->poc = devm_regulator_get_optional(dev, poc_name);
+ if (IS_ERR(rxport->poc)) {
+ ret = PTR_ERR(rxport->poc);
+ if (ret == -ENODEV) {
+ rxport->poc = NULL;
+ } else {
+ dev_err(dev, "rx: failed to get POC supply: %d\n", ret);
+ goto err_put_source_ep_fwnode;
+ }
+ }
+
+ return 0;
+
+err_put_source_ep_fwnode:
+ fwnode_handle_put(rxport->source.ep_fwnode);
+ return ret;
+}
+
+static int max96714_parse_dt(struct max96714_priv *priv)
+{
+ int ret;
+
+ ret = max96714_parse_dt_txport(priv);
+ if (ret)
+ return ret;
+
+ ret = max96714_parse_dt_rxport(priv);
+ /* The deserializer can create a test pattern even if the
+ * rx port is not connected to a serializer.
+ */
+ if (ret && ret == -ENOENT)
+ ret = 0;
+
+ return ret;
+}
+
+static int max96714_enable_core_hw(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u64 val;
+ int ret;
+
+ if (priv->pd_gpio) {
+ /* wait min 2 ms for reset to complete */
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+ fsleep(2000);
+ gpiod_set_value_cansleep(priv->pd_gpio, 0);
+ /* wait min 2 ms for power up to finish */
+ fsleep(2000);
+ }
+
+ ret = cci_read(priv->regmap, MAX96714_REG13, &val, NULL);
+ if (ret) {
+ dev_err_probe(dev, ret, "Cannot read first register, abort\n");
+ goto err_pd_gpio;
+ }
+
+ if (val != MAX96714_DEVICE_ID && val != MAX96714F_DEVICE_ID) {
+ dev_err(dev, "Unsupported device id expected %x got %x\n",
+ MAX96714F_DEVICE_ID, (u8)val);
+ ret = -EOPNOTSUPP;
+ goto err_pd_gpio;
+ }
+
+ ret = cci_read(priv->regmap, MAX96714_DEV_REV, &val, NULL);
+ if (ret)
+ goto err_pd_gpio;
+
+ dev_dbg(dev, "Found %x (rev %lx)\n", MAX96714F_DEVICE_ID,
+ (u8)val & MAX96714_DEV_REV_MASK);
+
+ ret = cci_read(priv->regmap, MAX96714_MIPI_TX52, &val, NULL);
+ if (ret)
+ goto err_pd_gpio;
+
+ if (!(val & MAX96714_TUN_EN)) {
+ dev_err(dev, "Only supporting tunnel mode");
+ ret = -EOPNOTSUPP;
+ goto err_pd_gpio;
+ }
+
+ return 0;
+
+err_pd_gpio:
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+ return ret;
+}
+
+static void max96714_disable_core_hw(struct max96714_priv *priv)
+{
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+}
+
+static int max96714_get_hw_resources(struct max96714_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+
+ priv->regmap = devm_cci_regmap_init_i2c(priv->client, 16);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ priv->pd_gpio =
+ devm_gpiod_get_optional(dev, "powerdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->pd_gpio))
+ return dev_err_probe(dev, PTR_ERR(priv->pd_gpio),
+ "Cannot get powerdown GPIO\n");
+ return 0;
+}
+
+static int max96714_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct max96714_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->client = client;
+
+ ret = max96714_get_hw_resources(priv);
+ if (ret)
+ return ret;
+
+ ret = max96714_enable_core_hw(priv);
+ if (ret)
+ return ret;
+
+ ret = max96714_parse_dt(priv);
+ if (ret)
+ goto err_disable_core_hw;
+
+ max96714_init_tx_port(priv);
+
+ ret = max96714_rxport_enable_poc(priv);
+ if (ret)
+ goto err_free_ports;
+
+ ret = max96714_i2c_mux_init(priv);
+ if (ret)
+ goto err_disable_poc;
+
+ ret = max96714_create_subdev(priv);
+ if (ret)
+ goto err_del_mux;
+
+ return 0;
+
+err_del_mux:
+ i2c_mux_del_adapters(priv->mux);
+err_disable_poc:
+ max96714_rxport_disable_poc(priv);
+err_free_ports:
+ fwnode_handle_put(priv->rxport.source.ep_fwnode);
+err_disable_core_hw:
+ max96714_disable_core_hw(priv);
+
+ return ret;
+}
+
+static void max96714_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct max96714_priv *priv = sd_to_max96714(sd);
+
+ max96714_destroy_subdev(priv);
+ i2c_mux_del_adapters(priv->mux);
+ max96714_rxport_disable_poc(priv);
+ fwnode_handle_put(priv->rxport.source.ep_fwnode);
+ max96714_disable_core_hw(priv);
+ gpiod_set_value_cansleep(priv->pd_gpio, 1);
+}
+
+static const struct of_device_id max96714_of_ids[] = {
+ { .compatible = "maxim,max96714f" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max96714_of_ids);
+
+static struct i2c_driver max96714_i2c_driver = {
+ .driver = {
+ .name = "max96714",
+ .of_match_table = max96714_of_ids,
+ },
+ .probe = max96714_probe,
+ .remove = max96714_remove,
+};
+
+module_i2c_driver(max96714_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Maxim Integrated GMSL2 Deserializers Driver");
+MODULE_AUTHOR("Julien Massot <julien.massot@collabora.com>");
--
2.44.0
^ permalink raw reply related
* [PATCH v6 3/4] media: i2c: add MAX96717 driver
From: Julien Massot @ 2024-03-25 13:16 UTC (permalink / raw)
To: linux-media
Cc: devicetree, kernel, linux-kernel, mchehab, robh+dt,
krzysztof.kozlowski+dt, conor+dt, sakari.ailus, Julien Massot
In-Reply-To: <20240325131634.165361-1-julien.massot@collabora.com>
This driver handles the MAX96717 serializer in tunnel mode.
All incoming CSI traffic will be tunneled through the GMSL2
link.
The MAX96717 driver can handle MAX96717 and MAX96717F variants
with the same "maxim,max96717f" compatible.
Signed-off-by: Julien Massot <julien.massot@collabora.com>
---
Change since v5:
- set the driver compatible back to MAX96717F that can be used as a fallback for MAX96717
Change since v4:
- make the driver compatible with MAX96717 instead of MAX96717F
- Add the device id for the MAX96717
- remove hw_data structure for now, it can be usefull later for handling different serializers e.g max9295
Change since v3:
- Maintainers: align to the new binding path
- Kconfig: better describe the symbol
- store the v4l2_mbus_config_mipi_csi2 structure instead of the full endpoint in the driver private structure
- use MAX96717_PAD_SINK/SOURCE instead of 0/1 for pad intialization
- Removed incorrect call to fwnode_handle_put(priv->sd.fwnode)
- Use unsigned int instead of u8
- Allocate clk name out of the clk struct initialization
- fixed multiline comment
- Removed one unnecessary goto at the end of the probe function
Change since v2:
- Use CCI helpers instead of recoding register access
- add missing bitfield header
---
MAINTAINERS | 7 +
drivers/media/i2c/Kconfig | 14 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/max96717.c | 934 +++++++++++++++++++++++++++++++++++
4 files changed, 956 insertions(+)
create mode 100644 drivers/media/i2c/max96717.c
diff --git a/MAINTAINERS b/MAINTAINERS
index b43102ca365d..c43088157f6d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13277,6 +13277,13 @@ S: Maintained
F: Documentation/devicetree/bindings/media/i2c/maxim,max96712.yaml
F: drivers/staging/media/max96712/max96712.c
+MAX96717 GMSL2 SERIALIZER DRIVER
+M: Julien Massot <julien.massot@collabora.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
+F: drivers/media/i2c/max96717.c
+
MAX9860 MONO AUDIO VOICE CODEC DRIVER
M: Peter Rosin <peda@axentia.se>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 56f276b920ab..1a99396edbcf 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -1573,6 +1573,20 @@ config VIDEO_DS90UB960
Device driver for the Texas Instruments DS90UB960
FPD-Link III Deserializer and DS90UB9702 FPD-Link IV Deserializer.
+config VIDEO_MAX96717
+ tristate "Maxim MAX96717 GMSL2 Serializer support"
+ depends on OF && I2C && VIDEO_DEV && COMMON_CLK
+ select I2C_MUX
+ select GPIOLIB
+ select V4L2_CCI_I2C
+ help
+ Device driver for the Maxim MAX96717 GMSL2 Serializer.
+ MAX96717 serializers convert video on a MIPI CSI-2
+ input to a GMSL2 output.
+
+ To compile this driver as a module, choose M here: the
+ module will be called max96717.
+
endmenu
endif # VIDEO_DEV
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index dfbe6448b549..9e007116f929 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_VIDEO_LM3646) += lm3646.o
obj-$(CONFIG_VIDEO_M52790) += m52790.o
obj-$(CONFIG_VIDEO_MAX9271_LIB) += max9271.o
obj-$(CONFIG_VIDEO_MAX9286) += max9286.o
+obj-$(CONFIG_VIDEO_MAX96717) += max96717.o
obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o
diff --git a/drivers/media/i2c/max96717.c b/drivers/media/i2c/max96717.c
new file mode 100644
index 000000000000..9ff0bc58b6a9
--- /dev/null
+++ b/drivers/media/i2c/max96717.c
@@ -0,0 +1,934 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Maxim GMSL2 Serializer Driver
+ *
+ * Copyright (C) 2024 Collabora Ltd.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/fwnode.h>
+#include <linux/gpio/driver.h>
+#include <linux/i2c-mux.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+
+#include <media/v4l2-cci.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX96717_DEVICE_ID 0xbf
+#define MAX96717F_DEVICE_ID 0xc8
+#define MAX96717_PORTS 2
+#define MAX96717_PAD_SINK 0
+#define MAX96717_PAD_SOURCE 1
+
+#define MAX96717_DEFAULT_CLKOUT_RATE 24000000UL
+
+/* DEV */
+#define REG3 CCI_REG8(0x3)
+#define MAX96717_RCLKSEL GENMASK(1, 0)
+#define RCLKSEL_REF_PLL CCI_REG8(0x3)
+#define MAX96717_REG6 CCI_REG8(0x6)
+#define RCLKEN BIT(5)
+#define MAX96717_DEV_ID CCI_REG8(0xd)
+#define MAX96717_DEV_REV CCI_REG8(0xe)
+#define MAX96717_DEV_REV_MASK GENMASK(3, 0)
+
+/* VID_TX Z */
+#define MAX96717_VIDEO_TX2 CCI_REG8(0x112)
+#define MAX96717_VIDEO_PCLKDET BIT(7)
+
+/* GPIO */
+#define MAX96717_NUM_GPIO 11
+#define MAX96717_GPIO_REG_A(gpio) CCI_REG8(0x2be + (gpio) * 3)
+#define MAX96717_GPIO_OUT BIT(4)
+#define MAX96717_GPIO_IN BIT(3)
+#define MAX96717_GPIO_RX_EN BIT(2)
+#define MAX96717_GPIO_TX_EN BIT(1)
+#define MAX96717_GPIO_OUT_DIS BIT(0)
+
+/* FRONTTOP */
+/* MAX96717 only have CSI port 'B' */
+#define MAX96717_FRONTOP0 CCI_REG8(0x308)
+#define MAX96717_START_PORT_B BIT(5)
+
+/* MIPI_RX */
+#define MAX96717_MIPI_RX1 CCI_REG8(0x331)
+#define MAX96717_MIPI_LANES_CNT GENMASK(5, 4)
+#define MAX96717_MIPI_RX2 CCI_REG8(0x332) /* phy1 Lanes map */
+#define MAX96717_PHY2_LANES_MAP GENMASK(7, 4)
+#define MAX96717_MIPI_RX3 CCI_REG8(0x333) /* phy2 Lanes map */
+#define MAX96717_PHY1_LANES_MAP GENMASK(3, 0)
+#define MAX96717_MIPI_RX4 CCI_REG8(0x334) /* phy1 lane polarities */
+#define MAX96717_PHY1_LANES_POL GENMASK(6, 4)
+#define MAX96717_MIPI_RX5 CCI_REG8(0x335) /* phy2 lane polarities */
+#define MAX96717_PHY2_LANES_POL GENMASK(2, 0)
+
+/* MIPI_RX_EXT */
+#define MAX96717_MIPI_RX_EXT11 CCI_REG8(0x383)
+#define MAX96717_TUN_MODE BIT(7)
+
+/* REF_VTG */
+#define REF_VTG0 CCI_REG8(0x3f0)
+#define REFGEN_PREDEF_EN BIT(6)
+#define REFGEN_PREDEF_FREQ_MASK GENMASK(5, 4)
+#define REFGEN_PREDEF_FREQ_ALT BIT(3)
+#define REFGEN_RST BIT(1)
+#define REFGEN_EN BIT(0)
+
+/* MISC */
+#define PIO_SLEW_1 CCI_REG8(0x570)
+
+struct max96717_priv {
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct i2c_mux_core *mux;
+ struct v4l2_mbus_config_mipi_csi2 mipi_csi2;
+ struct v4l2_subdev sd;
+ struct media_pad pads[MAX96717_PORTS];
+ struct v4l2_async_notifier notifier;
+ struct v4l2_subdev *source_sd;
+ u16 source_sd_pad;
+ u64 enabled_source_streams;
+ u8 pll_predef_index;
+ struct clk_hw clk_hw;
+ struct gpio_chip gpio_chip;
+};
+
+static inline struct max96717_priv *sd_to_max96717(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct max96717_priv, sd);
+}
+
+static inline struct max96717_priv *clk_hw_to_max96717(struct clk_hw *hw)
+{
+ return container_of(hw, struct max96717_priv, clk_hw);
+}
+
+static int max96717_i2c_mux_select(struct i2c_mux_core *mux, u32 chan)
+{
+ return 0;
+}
+
+static int max96717_i2c_mux_init(struct max96717_priv *priv)
+{
+ priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev,
+ 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
+ max96717_i2c_mux_select, NULL);
+ if (!priv->mux)
+ return -ENOMEM;
+
+ return i2c_mux_add_adapter(priv->mux, 0, 0, 0);
+}
+
+static inline int max96717_start_csi(struct max96717_priv *priv, bool start)
+{
+ return cci_update_bits(priv->regmap, MAX96717_FRONTOP0,
+ MAX96717_START_PORT_B,
+ start ? MAX96717_START_PORT_B : 0, NULL);
+}
+
+static int max96717_gpiochip_get(struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+ u64 val;
+ int ret;
+
+ ret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ &val, NULL);
+ if (ret)
+ return ret;
+
+ if (val & MAX96717_GPIO_OUT_DIS)
+ return !!(val & MAX96717_GPIO_IN);
+ else
+ return !!(val & MAX96717_GPIO_OUT);
+}
+
+static void max96717_gpiochip_set(struct gpio_chip *gpiochip,
+ unsigned int offset, int value)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+
+ cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ MAX96717_GPIO_OUT, MAX96717_GPIO_OUT, NULL);
+}
+
+static int max96717_gpio_get_direction(struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+ u64 val;
+ int ret;
+
+ ret = cci_read(priv->regmap, MAX96717_GPIO_REG_A(offset), &val, NULL);
+ if (ret < 0)
+ return ret;
+
+ return !!(val & MAX96717_GPIO_OUT_DIS);
+}
+
+static int max96717_gpio_direction_out(struct gpio_chip *gpiochip,
+ unsigned int offset, int value)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+
+ return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ MAX96717_GPIO_OUT_DIS | MAX96717_GPIO_OUT,
+ value ? MAX96717_GPIO_OUT : 0, NULL);
+}
+
+static int max96717_gpio_direction_in(struct gpio_chip *gpiochip,
+ unsigned int offset)
+{
+ struct max96717_priv *priv = gpiochip_get_data(gpiochip);
+
+ return cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(offset),
+ MAX96717_GPIO_OUT_DIS, MAX96717_GPIO_OUT_DIS,
+ NULL);
+}
+
+static int max96717_gpiochip_probe(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct gpio_chip *gc = &priv->gpio_chip;
+ int ret, i;
+
+ gc->label = dev_name(dev);
+ gc->parent = dev;
+ gc->owner = THIS_MODULE;
+ gc->ngpio = MAX96717_NUM_GPIO;
+ gc->base = -1;
+ gc->can_sleep = true;
+ gc->get_direction = max96717_gpio_get_direction;
+ gc->direction_input = max96717_gpio_direction_in;
+ gc->direction_output = max96717_gpio_direction_out;
+ gc->set = max96717_gpiochip_set;
+ gc->get = max96717_gpiochip_get;
+ gc->of_gpio_n_cells = 2;
+
+ /* Disable GPIO forwarding */
+ for (i = 0; i < gc->ngpio; i++)
+ cci_update_bits(priv->regmap, MAX96717_GPIO_REG_A(i),
+ MAX96717_GPIO_RX_EN | MAX96717_GPIO_TX_EN,
+ 0, &ret);
+
+ if (ret)
+ return ret;
+
+ ret = devm_gpiochip_add_data(dev, gc, priv);
+ if (ret) {
+ dev_err(dev, "Unable to create gpio_chip\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int _max96717_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_krouting *routing)
+{
+ static const struct v4l2_mbus_framefmt format = {
+ .width = 1280,
+ .height = 1080,
+ .code = MEDIA_BUS_FMT_Y8_1X8,
+ .field = V4L2_FIELD_NONE,
+ };
+ int ret;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int max96717_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE && priv->enabled_source_streams)
+ return -EBUSY;
+
+ return _max96717_set_routing(sd, state, routing);
+}
+
+static int max96717_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_format *format)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ struct v4l2_mbus_framefmt *fmt;
+ u64 stream_source_mask;
+
+ if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE &&
+ priv->enabled_source_streams)
+ return -EBUSY;
+
+ /* No transcoding, source and sink formats must match. */
+ if (format->pad == MAX96717_PAD_SOURCE)
+ return v4l2_subdev_get_fmt(sd, state, format);
+
+ /* Set sink format */
+ fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = format->format;
+
+ /* Propagate to source format */
+ fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+ format->stream);
+ if (!fmt)
+ return -EINVAL;
+ *fmt = format->format;
+
+ stream_source_mask = BIT(format->stream);
+
+ return v4l2_subdev_state_xlate_streams(state, MAX96717_PAD_SOURCE,
+ MAX96717_PAD_SINK,
+ &stream_source_mask);
+}
+
+static int max96717_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state)
+{
+ struct v4l2_subdev_route routes[] = {
+ {
+ .sink_pad = MAX96717_PAD_SINK,
+ .sink_stream = 0,
+ .source_pad = MAX96717_PAD_SOURCE,
+ .source_stream = 0,
+ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+ },
+ };
+ struct v4l2_subdev_krouting routing = {
+ .num_routes = ARRAY_SIZE(routes),
+ .routes = routes,
+ };
+
+ return _max96717_set_routing(sd, state, &routing);
+}
+
+static bool max96717_pipe_pclkdet(struct max96717_priv *priv)
+{
+ u64 val = 0;
+
+ cci_read(priv->regmap, MAX96717_VIDEO_TX2, &val, NULL);
+
+ return val & MAX96717_VIDEO_PCLKDET;
+}
+
+static int max96717_log_status(struct v4l2_subdev *sd)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ struct device *dev = &priv->client->dev;
+
+ dev_info(dev, "Serializer: max96717\n");
+ dev_info(dev, "Pipe: pclkdet:%d\n", max96717_pipe_pclkdet(priv));
+
+ return 0;
+}
+
+static int max96717_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ struct device *dev = &priv->client->dev;
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ MAX96717_PAD_SOURCE,
+ MAX96717_PAD_SINK,
+ &streams_mask);
+
+ if (!priv->enabled_source_streams)
+ max96717_start_csi(priv, true);
+
+ ret = v4l2_subdev_enable_streams(priv->source_sd, priv->source_sd_pad,
+ sink_streams);
+ if (ret) {
+ dev_err(dev, "Fail to start streams:%llu on remote subdev\n",
+ sink_streams);
+ goto stop_csi;
+ }
+
+ priv->enabled_source_streams |= streams_mask;
+
+ return 0;
+
+stop_csi:
+ if (!priv->enabled_source_streams)
+ max96717_start_csi(priv, false);
+ return ret;
+}
+
+static int max96717_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
+{
+ struct max96717_priv *priv = sd_to_max96717(sd);
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ MAX96717_PAD_SOURCE,
+ MAX96717_PAD_SINK,
+ &streams_mask);
+
+ ret = v4l2_subdev_disable_streams(priv->source_sd, priv->source_sd_pad,
+ sink_streams);
+ if (ret)
+ return ret;
+
+ priv->enabled_source_streams &= ~streams_mask;
+
+ if (!priv->enabled_source_streams)
+ max96717_start_csi(priv, false);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_pad_ops max96717_pad_ops = {
+ .enable_streams = max96717_enable_streams,
+ .disable_streams = max96717_disable_streams,
+ .set_routing = max96717_set_routing,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = max96717_set_fmt,
+};
+
+static const struct v4l2_subdev_core_ops max96717_subdev_core_ops = {
+ .log_status = max96717_log_status,
+};
+
+static const struct v4l2_subdev_internal_ops max96717_internal_ops = {
+ .init_state = max96717_init_state,
+};
+
+static const struct v4l2_subdev_ops max96717_subdev_ops = {
+ .core = &max96717_subdev_core_ops,
+ .pad = &max96717_pad_ops,
+};
+
+static const struct media_entity_operations max96717_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static int max96717_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *source_subdev,
+ struct v4l2_async_connection *asd)
+{
+ struct max96717_priv *priv = sd_to_max96717(notifier->sd);
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ ret = media_entity_get_fwnode_pad(&source_subdev->entity,
+ source_subdev->fwnode,
+ MEDIA_PAD_FL_SOURCE);
+ if (ret < 0) {
+ dev_err(dev, "Failed to find pad for %s\n",
+ source_subdev->name);
+ return ret;
+ }
+
+ priv->source_sd = source_subdev;
+ priv->source_sd_pad = ret;
+
+ ret = media_create_pad_link(&source_subdev->entity, priv->source_sd_pad,
+ &priv->sd.entity, 0,
+ MEDIA_LNK_FL_ENABLED |
+ MEDIA_LNK_FL_IMMUTABLE);
+ if (ret) {
+ dev_err(dev, "Unable to link %s:%u -> %s:0\n",
+ source_subdev->name, priv->source_sd_pad,
+ priv->sd.name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations max96717_notify_ops = {
+ .bound = max96717_notify_bound,
+};
+
+static int max96717_v4l2_notifier_register(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct v4l2_async_connection *asd;
+ struct fwnode_handle *ep_fwnode;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96717_PAD_SINK, 0, 0);
+ if (!ep_fwnode) {
+ dev_err(dev, "No graph endpoint\n");
+ return -ENODEV;
+ }
+
+ v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd);
+
+ asd = v4l2_async_nf_add_fwnode_remote(&priv->notifier, ep_fwnode,
+ struct v4l2_async_connection);
+
+ fwnode_handle_put(ep_fwnode);
+
+ if (IS_ERR(asd)) {
+ dev_err(dev, "Failed to add subdev: %ld", PTR_ERR(asd));
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return PTR_ERR(asd);
+ }
+
+ priv->notifier.ops = &max96717_notify_ops;
+
+ ret = v4l2_async_nf_register(&priv->notifier);
+ if (ret) {
+ dev_err(dev, "Failed to register subdev_notifier");
+ v4l2_async_nf_cleanup(&priv->notifier);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void max96717_v4l2_notifier_unregister(struct max96717_priv *priv)
+{
+ v4l2_async_nf_unregister(&priv->notifier);
+ v4l2_async_nf_cleanup(&priv->notifier);
+}
+
+static int max96717_subdev_init(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ int ret;
+
+ v4l2_i2c_subdev_init(&priv->sd, priv->client, &max96717_subdev_ops);
+ priv->sd.internal_ops = &max96717_internal_ops;
+
+ priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_STREAMS;
+ priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+ priv->sd.entity.ops = &max96717_entity_ops;
+
+ priv->pads[MAX96717_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+ priv->pads[MAX96717_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&priv->sd.entity, 2, priv->pads);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to init pads\n");
+
+ ret = v4l2_subdev_init_finalize(&priv->sd);
+ if (ret) {
+ dev_err_probe(dev, ret,
+ "v4l2 subdev init finalized failed\n");
+ goto err_entity_cleanup;
+ }
+ ret = max96717_v4l2_notifier_register(priv);
+ if (ret) {
+ dev_err_probe(dev, ret,
+ "v4l2 subdev notifier register failed\n");
+ goto err_free_state;
+ }
+
+ ret = v4l2_async_register_subdev(&priv->sd);
+ if (ret) {
+ dev_err_probe(dev, ret, "v4l2_async_register_subdev error\n");
+ goto err_unreg_notif;
+ }
+
+ return 0;
+
+err_unreg_notif:
+ max96717_v4l2_notifier_unregister(priv);
+err_free_state:
+ v4l2_subdev_cleanup(&priv->sd);
+err_entity_cleanup:
+ media_entity_cleanup(&priv->sd.entity);
+
+ return ret;
+}
+
+static void max96717_subdev_uninit(struct max96717_priv *priv)
+{
+ v4l2_async_unregister_subdev(&priv->sd);
+ max96717_v4l2_notifier_unregister(priv);
+ v4l2_subdev_cleanup(&priv->sd);
+ media_entity_cleanup(&priv->sd.entity);
+}
+
+struct max96717_pll_predef_freq {
+ unsigned long freq;
+ bool is_alt;
+ u8 val;
+};
+
+static const struct max96717_pll_predef_freq max96717_predef_freqs[] = {
+ { 13500000, true, 0 }, { 19200000, false, 0 },
+ { 24000000, true, 1 }, { 27000000, false, 1 },
+ { 37125000, false, 2 }, { 74250000, false, 3 },
+};
+
+static unsigned long
+max96717_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+
+ return max96717_predef_freqs[priv->pll_predef_index].freq;
+}
+
+static unsigned int max96717_clk_find_best_index(struct max96717_priv *priv,
+ unsigned long rate)
+{
+ unsigned int i, idx;
+ unsigned long diff_new, diff_old;
+
+ diff_old = U32_MAX;
+ idx = 0;
+
+ for (i = 0; i < ARRAY_SIZE(max96717_predef_freqs); i++) {
+ diff_new = abs(rate - max96717_predef_freqs[i].freq);
+ if (diff_new < diff_old) {
+ diff_old = diff_new;
+ idx = i;
+ }
+ }
+
+ return idx;
+}
+
+static long max96717_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+ struct device *dev = &priv->client->dev;
+ unsigned int idx;
+
+ idx = max96717_clk_find_best_index(priv, rate);
+
+ if (rate != max96717_predef_freqs[idx].freq) {
+ dev_warn(dev, "Request CLK freq:%lu, found CLK freq:%lu\n",
+ rate, max96717_predef_freqs[idx].freq);
+ }
+
+ return max96717_predef_freqs[idx].freq;
+}
+
+static int max96717_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+ unsigned int val, idx;
+ int ret = 0;
+
+ idx = max96717_clk_find_best_index(priv, rate);
+
+ val = FIELD_PREP(REFGEN_PREDEF_FREQ_MASK,
+ max96717_predef_freqs[idx].val);
+
+ if (max96717_predef_freqs[idx].is_alt)
+ val |= REFGEN_PREDEF_FREQ_ALT;
+
+ val |= REFGEN_RST | REFGEN_PREDEF_EN;
+
+ cci_write(priv->regmap, REF_VTG0, val, &ret);
+ cci_update_bits(priv->regmap, REF_VTG0, REFGEN_RST | REFGEN_EN,
+ REFGEN_EN, &ret);
+ if (ret)
+ return ret;
+
+ priv->pll_predef_index = idx;
+
+ return 0;
+}
+
+static int max96717_clk_prepare(struct clk_hw *hw)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+
+ return cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN,
+ RCLKEN, NULL);
+}
+
+static void max96717_clk_unprepare(struct clk_hw *hw)
+{
+ struct max96717_priv *priv = clk_hw_to_max96717(hw);
+
+ cci_update_bits(priv->regmap, MAX96717_REG6, RCLKEN, 0, NULL);
+}
+
+static const struct clk_ops max96717_clk_ops = {
+ .prepare = max96717_clk_prepare,
+ .unprepare = max96717_clk_unprepare,
+ .set_rate = max96717_clk_set_rate,
+ .recalc_rate = max96717_clk_recalc_rate,
+ .round_rate = max96717_clk_round_rate,
+};
+
+static int max96717_register_clkout(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct clk_init_data init = { .ops = &max96717_clk_ops };
+ int ret;
+
+ init.name = kasprintf(GFP_KERNEL, "max96717.%s.clk_out",
+ dev_name(dev));
+ if (!init.name)
+ return -ENOMEM;
+
+ /* RCLKSEL Reference PLL output */
+ ret = cci_update_bits(priv->regmap, REG3, MAX96717_RCLKSEL,
+ RCLKSEL_REF_PLL, NULL);
+ /* MFP4 fastest slew rate */
+ cci_update_bits(priv->regmap, PIO_SLEW_1, BIT(5) | BIT(4), 0, &ret);
+ if (ret)
+ goto free_init_name;
+
+ priv->clk_hw.init = &init;
+
+ /* Initialize to 24 MHz */
+ ret = max96717_clk_set_rate(&priv->clk_hw,
+ MAX96717_DEFAULT_CLKOUT_RATE, 0);
+ if (ret < 0)
+ goto free_init_name;
+
+ ret = devm_clk_hw_register(dev, &priv->clk_hw);
+ kfree(init.name);
+ if (ret)
+ return dev_err_probe(dev, ret, "Cannot register clock HW\n");
+
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+ &priv->clk_hw);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Cannot add OF clock provider\n");
+
+ return 0;
+
+free_init_name:
+ kfree(init.name);
+ return ret;
+}
+
+static int max96717_init_csi_lanes(struct max96717_priv *priv)
+{
+ struct v4l2_mbus_config_mipi_csi2 *mipi = &priv->mipi_csi2;
+ unsigned long lanes_used = 0;
+ unsigned int nlanes, lane, val = 0;
+ int ret;
+
+ nlanes = mipi->num_data_lanes;
+
+ ret = cci_update_bits(priv->regmap, MAX96717_MIPI_RX1,
+ MAX96717_MIPI_LANES_CNT,
+ FIELD_PREP(MAX96717_MIPI_LANES_CNT,
+ nlanes - 1), NULL);
+
+ /* lanes polarity */
+ for (lane = 0; lane < nlanes + 1; lane++) {
+ if (!mipi->lane_polarities[lane])
+ continue;
+ /* Clock lane */
+ if (lane == 0)
+ val |= BIT(2);
+ else if (lane < 3)
+ val |= BIT(lane - 1);
+ else
+ val |= BIT(lane);
+ }
+
+ cci_update_bits(priv->regmap, MAX96717_MIPI_RX5,
+ MAX96717_PHY2_LANES_POL,
+ FIELD_PREP(MAX96717_PHY2_LANES_POL, val), &ret);
+
+ cci_update_bits(priv->regmap, MAX96717_MIPI_RX4,
+ MAX96717_PHY1_LANES_POL,
+ FIELD_PREP(MAX96717_PHY1_LANES_POL,
+ val >> 3), &ret);
+ /* lanes mapping */
+ for (lane = 0, val = 0; lane < nlanes; lane++) {
+ val |= (mipi->data_lanes[lane] - 1) << (lane * 2);
+ lanes_used |= BIT(mipi->data_lanes[lane] - 1);
+ }
+
+ /*
+ * Unused lanes need to be mapped as well to not have
+ * the same lanes mapped twice.
+ */
+ for (; lane < 4; lane++) {
+ unsigned int idx = find_first_zero_bit(&lanes_used, 4);
+
+ val |= idx << (lane * 2);
+ lanes_used |= BIT(idx);
+ }
+
+ cci_update_bits(priv->regmap, MAX96717_MIPI_RX3,
+ MAX96717_PHY1_LANES_MAP,
+ FIELD_PREP(MAX96717_PHY1_LANES_MAP, val), &ret);
+
+ return cci_update_bits(priv->regmap, MAX96717_MIPI_RX2,
+ MAX96717_PHY2_LANES_MAP,
+ FIELD_PREP(MAX96717_PHY2_LANES_MAP, val >> 4),
+ &ret);
+}
+
+static int max96717_hw_init(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ u64 dev_id, val;
+ int ret;
+
+ ret = cci_read(priv->regmap, MAX96717_DEV_ID, &dev_id, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Fail to read the device id\n");
+
+ if (dev_id != MAX96717_DEVICE_ID && dev_id != MAX96717F_DEVICE_ID)
+ return dev_err_probe(dev, -EOPNOTSUPP,
+ "Unsupported device id got %x\n", (u8)dev_id);
+
+ ret = cci_read(priv->regmap, MAX96717_DEV_REV, &val, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Fail to read device revision");
+
+ dev_dbg(dev, "Found %x (rev %lx)\n", (u8)dev_id,
+ (u8)val & MAX96717_DEV_REV_MASK);
+
+ ret = cci_read(priv->regmap, MAX96717_MIPI_RX_EXT11, &val, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Fail to read mipi rx extension");
+
+ if (!(val & MAX96717_TUN_MODE))
+ return dev_err_probe(dev, -EOPNOTSUPP,
+ "Only supporting tunnel mode");
+
+ return max96717_init_csi_lanes(priv);
+}
+
+static int max96717_parse_dt(struct max96717_priv *priv)
+{
+ struct device *dev = &priv->client->dev;
+ struct v4l2_fwnode_endpoint vep = {
+ .bus_type = V4L2_MBUS_CSI2_DPHY
+ };
+ struct fwnode_handle *ep_fwnode;
+ unsigned char num_data_lanes;
+ int ret;
+
+ ep_fwnode = fwnode_graph_get_endpoint_by_id(dev_fwnode(dev),
+ MAX96717_PAD_SINK, 0, 0);
+ if (!ep_fwnode)
+ return dev_err_probe(dev, -ENOENT, "no endpoint found\n");
+
+ ret = v4l2_fwnode_endpoint_parse(ep_fwnode, &vep);
+
+ fwnode_handle_put(ep_fwnode);
+
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to parse sink endpoint");
+
+ num_data_lanes = vep.bus.mipi_csi2.num_data_lanes;
+ if (num_data_lanes < 1 || num_data_lanes > 4)
+ return dev_err_probe(dev, -EINVAL,
+ "Invalid data lanes must be 1 to 4\n");
+
+ memcpy(&priv->mipi_csi2, &vep.bus.mipi_csi2, sizeof(priv->mipi_csi2));
+
+ return 0;
+}
+
+static int max96717_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct max96717_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->client = client;
+ i2c_set_clientdata(client, priv);
+
+ priv->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(priv->regmap)) {
+ ret = PTR_ERR(priv->regmap);
+ return dev_err_probe(dev, ret, "Failed to init regmap\n");
+ }
+
+ ret = max96717_parse_dt(priv);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to parse the dt\n");
+
+ ret = max96717_hw_init(priv);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to initialize the hardware\n");
+
+ ret = max96717_gpiochip_probe(priv);
+ if (ret) {
+ dev_err(&client->dev, "Failed to init gpiochip\n");
+ return ret;
+ }
+
+ ret = max96717_register_clkout(priv);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to register clkout\n");
+
+ ret = max96717_subdev_init(priv);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Failed to initialize v4l2 subdev\n");
+
+ ret = max96717_i2c_mux_init(priv);
+ if (ret) {
+ dev_err_probe(dev, ret, "failed to add remote i2c adapter\n");
+ max96717_subdev_uninit(priv);
+ }
+
+ return ret;
+}
+
+static void max96717_remove(struct i2c_client *client)
+{
+ struct max96717_priv *priv = i2c_get_clientdata(client);
+
+ max96717_subdev_uninit(priv);
+ i2c_mux_del_adapters(priv->mux);
+}
+
+static const struct of_device_id max96717_of_ids[] = {
+ { .compatible = "maxim,max96717f" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, max96717_of_ids);
+
+static struct i2c_driver max96717_i2c_driver = {
+ .driver = {
+ .name = "max96717",
+ .of_match_table = max96717_of_ids,
+ },
+ .probe = max96717_probe,
+ .remove = max96717_remove,
+};
+
+module_i2c_driver(max96717_i2c_driver);
+
+MODULE_DESCRIPTION("Maxim GMSL2 MAX96717 Serializer Driver");
+MODULE_AUTHOR("Julien Massot <julien.massot@collabora.com>");
+MODULE_LICENSE("GPL");
--
2.44.0
^ permalink raw reply related
* [PATCH v6 2/4] dt-bindings: media: add Maxim MAX96714 GMSL2 Deserializer
From: Julien Massot @ 2024-03-25 13:16 UTC (permalink / raw)
To: linux-media
Cc: devicetree, kernel, linux-kernel, mchehab, robh+dt,
krzysztof.kozlowski+dt, conor+dt, sakari.ailus, Julien Massot
In-Reply-To: <20240325131634.165361-1-julien.massot@collabora.com>
Add DT bindings for Maxim MAX96714 GMSL2 Deserializer.
Signed-off-by: Julien Massot <julien.massot@collabora.com>
---
Change since v5:
- Reverse the fallback MAX96714 can fallback to MAX96714F
- Use const instead of enum for MAX96714F compatible
Change since v4:
- Add compatible for MAX96714 and use it as a fallback for MAX96714F
- Remove extra '|' for decriptions
- Reference 'i2c-gate' instead of 'i2c-controller'
Change since v3:
- Renamed file to maxim,max96714.yaml dropped the 'f' suffix
- Removed mention to C-PHY since it's not supported by MAX96714 deserializers
- Removed bus-type requirement on CSI endpoint since the device only support D-PHY
- Removed the clock-lanes property in the dt example
Change since v2:
- remove reg description
- rename enable gpio to powerdown
- use generic node name: i2c, serializer, deserializer
---
.../bindings/media/i2c/maxim,max96714.yaml | 175 ++++++++++++++++++
1 file changed, 175 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
new file mode 100644
index 000000000000..fdcba14fcde9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96714.yaml
@@ -0,0 +1,175 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Collabora Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/maxim,max96714.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX96714 GMSL2 to CSI-2 Deserializer
+
+maintainers:
+ - Julien Massot <julien.massot@collabora.com>
+
+description:
+ The MAX96714 deserializer converts GMSL2 serial inputs into MIPI
+ CSI-2 D-PHY formatted output. The device allows the GMSL2 link to
+ simultaneously transmit bidirectional control-channel data while forward
+ video transmissions are in progress. The MAX96714 can connect to one
+ remotely located serializer using industry-standard coax or STP
+ interconnects. The device cans operate in pixel or tunnel mode. In pixel mode
+ the MAX96714 can select individual video stream, while the tunnel mode forward all
+ the MIPI data received by the serializer.
+
+ The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
+ forward direction and 187.5Mbps in the reverse direction.
+ MAX96714F only supports a fixed rate of 3Gbps in the forward direction.
+
+properties:
+ compatible:
+ oneOf:
+ - const: maxim,max96714f
+ - items:
+ - enum:
+ - maxim,max96714
+ - const: maxim,max96714f
+
+ reg:
+ maxItems: 1
+
+ powerdown-gpios:
+ maxItems: 1
+ description:
+ Specifier for the GPIO connected to the PWDNB pin.
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ unevaluatedProperties: false
+ description: GMSL Input
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+ description:
+ Endpoint for GMSL2-Link port.
+
+ port@1:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: CSI-2 Output port
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ lane-polarities:
+ minItems: 1
+ maxItems: 5
+
+ link-frequencies:
+ maxItems: 1
+
+ required:
+ - data-lanes
+
+ required:
+ - port@1
+
+ i2c-gate:
+ $ref: /schemas/i2c/i2c-gate.yaml
+ unevaluatedProperties: false
+ description:
+ The MAX96714 will pass through and forward the I2C requests from the
+ incoming I2C bus over the GMSL2 link. Therefore it supports an i2c-gate
+ subnode to configure a serializer.
+
+ port0-poc-supply:
+ description: Regulator providing Power over Coax for the GMSL port
+
+required:
+ - compatible
+ - reg
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/media/video-interfaces.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ deserializer@28 {
+ compatible = "maxim,max96714f";
+ reg = <0x28>;
+ powerdown-gpios = <&main_gpio0 37 GPIO_ACTIVE_LOW>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ max96714_gmsl_in: endpoint {
+ remote-endpoint = <&max96917f_gmsl_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ max96714_csi_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ link-frequencies = /bits/ 64 <400000000>;
+ remote-endpoint = <&csi_in>;
+ };
+ };
+ };
+
+ i2c-gate {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ serializer@40 {
+ compatible = "maxim,max96717f";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ max96717f_csi_in: endpoint {
+ bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+ data-lanes = <1 2>;
+ lane-polarities = <1 0 1>;
+ remote-endpoint = <&sensor_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ max96917f_gmsl_out: endpoint {
+ remote-endpoint = <&max96714_gmsl_in>;
+ };
+ };
+ };
+ };
+ };
+ };
+ };
+...
--
2.44.0
^ permalink raw reply related
* [PATCH v6 1/4] dt-bindings: media: add Maxim MAX96717 GMSL2 Serializer
From: Julien Massot @ 2024-03-25 13:16 UTC (permalink / raw)
To: linux-media
Cc: devicetree, kernel, linux-kernel, mchehab, robh+dt,
krzysztof.kozlowski+dt, conor+dt, sakari.ailus, Julien Massot
In-Reply-To: <20240325131634.165361-1-julien.massot@collabora.com>
Add DT bindings for Maxim MAX96717 GMSL2 Serializer.
Signed-off-by: Julien Massot <julien.massot@collabora.com>
---
Change since v5:
- Reverse the fallback MAX96717 can fallback to MAX96717F
- Use const instead of enum for MAX96717F compatible
Change since v4:
- Add compatible for MAX96717 and use it as a fallback for MAX96717F
- Remove extra '|' for decriptions
- Reference 'i2c-gate' instead of 'i2c-controller'
Change since v3:
- Renamed file to maxim,max96717.yaml dropped the 'f' suffix
- Added lane-polarities and bus type properties to the CSI endpoint
Change since v2:
- remove reg description
- add data lanes min/maxItems
- Use generic node name
---
.../bindings/media/i2c/maxim,max96717.yaml | 164 ++++++++++++++++++
1 file changed, 164 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
diff --git a/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
new file mode 100644
index 000000000000..ac8bf11a6fa5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/maxim,max96717.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2024 Collabora Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/i2c/maxim,max96717.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MAX96717 CSI-2 to GMSL2 Serializer
+
+maintainers:
+ - Julien Massot <julien.massot@collabora.com>
+
+description:
+ The MAX96717 serializer converts MIPI CSI-2 D-PHY or C-PHY formatted input
+ into GMSL2 serial outputs. The device allows the GMSL2 link to
+ simultaneously transmit bidirectional control-channel data while forward
+ video transmissions are in progress. The MAX96717 can connect to one
+ remotely located deserializer using industry-standard coax or STP
+ interconnects. The device cans operate in pixel or tunnel mode. In pixel mode
+ the MAX96717 can select the MIPI datatype, while the tunnel mode forward all the MIPI
+ data received by the serializer.
+ The MAX96717 supports Reference Over Reverse (channel),
+ to generate a clock output for the sensor from the GMSL reverse channel.
+
+ The GMSL2 serial link operates at a fixed rate of 3Gbps or 6Gbps in the
+ forward direction and 187.5Mbps in the reverse direction.
+ MAX96717F only supports a fixed rate of 3Gbps in the forward direction.
+
+properties:
+ compatible:
+ oneOf:
+ - const: maxim,max96717f
+ - items:
+ - enum:
+ - maxim,max96717
+ - const: maxim,max96717f
+
+ '#gpio-cells':
+ const: 2
+ description:
+ First cell is the GPIO pin number, second cell is the flags. The GPIO pin
+ number must be in range of [0, 10].
+
+ gpio-controller: true
+
+ '#clock-cells':
+ const: 0
+
+ reg:
+ maxItems: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/$defs/port-base
+ unevaluatedProperties: false
+ description: CSI-2 Input port
+
+ properties:
+ endpoint:
+ $ref: /schemas/media/video-interfaces.yaml#
+ unevaluatedProperties: false
+
+ properties:
+ data-lanes:
+ minItems: 1
+ maxItems: 4
+
+ lane-polarities:
+ minItems: 1
+ maxItems: 5
+
+ bus-type:
+ enum:
+ - 1 # MEDIA_BUS_TYPE_CSI2_CPHY
+ - 4 # MEDIA_BUS_TYPE_CSI2_DPHY
+
+ required:
+ - data-lanes
+ - bus-type
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ unevaluatedProperties: false
+ description: GMSL Output port
+
+ required:
+ - port@1
+
+ i2c-gate:
+ $ref: /schemas/i2c/i2c-gate.yaml
+ unevaluatedProperties: false
+ description:
+ The MAX96717 will forward the I2C requests from the
+ incoming GMSL2 link. Therefore, it supports an i2c-gate
+ subnode to configure a sensor.
+
+required:
+ - compatible
+ - reg
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+ #include <dt-bindings/media/video-interfaces.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ serializer: serializer@40 {
+ compatible = "maxim,max96717f";
+ reg = <0x40>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #clock-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ max96717f_csi_in: endpoint {
+ bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>;
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&sensor_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ max96917f_gmsl_out: endpoint {
+ remote-endpoint = <&deser_gmsl_in>;
+ };
+ };
+ };
+
+ i2c-gate {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sensor@10 {
+ compatible = "st,st-vgxy61";
+ reg = <0x10>;
+ reset-gpios = <&serializer 0 GPIO_ACTIVE_LOW>;
+ clocks = <&serializer>;
+ VCORE-supply = <&v1v2>;
+ VDDIO-supply = <&v1v8>;
+ VANA-supply = <&v2v8>;
+ port {
+ sensor_out: endpoint {
+ data-lanes = <1 2 3 4>;
+ remote-endpoint = <&max96717f_csi_in>;
+ };
+ };
+ };
+ };
+ };
+ };
+...
--
2.44.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox