From 5c6639e0ef90c141527675065463ce7d3cc3ab60 Mon Sep 17 00:00:00 2001 From: Chaoyi Chen Date: Thu, 16 Nov 2023 16:26:33 +0800 Subject: [PATCH 01/20] arm64: dts: rockchip: add lvds demo dts for rk3567/rk3568 This commit adds demo dts about the various possible uses of LVDS: 1. Single channel LVDS 2. Dual LVDS 3. Two Video Port use two separate single channel LVDS 4. One Video Port use two separate single channel LVDS For case 1, the video port outputs as follows: VP1 -> LVDS0 or VP1 -> LVDS1 or VP2 -> LVDS0 or VP2 -> LVDS1 For case 2, the video port outputs as follows: VP1 -> LVDS0, VP1 -> LVDS1 or VP2-> LVDS0, VP2-> LVDS1 For case 3, the video port outputs as follows: VP1 -> LVDS0, VP2 -> LVDS1 or VP1 -> LVDS1, VP2 -> LVDS0 For case 4, the video port outputs as follows: VP1 -> LVDS0, VP1 -> LVDS1 or VP2-> LVDS0, VP2-> LVDS1 Change-Id: I426ba9033863cc1442834daf8fa63aaa472274c5 Signed-off-by: Chaoyi Chen --- arch/arm64/boot/dts/rockchip/Makefile | 10 +- ...rk3567-evb2-lp4x-v10-dual-channel-lvds.dts | 108 +++++----- ...4x-v10-one-vp-two-single-channel-lvds.dts} | 88 ++++---- ...3567-evb2-lp4x-v10-single-channel-lvds.dts | 136 ++++++++++++ ...wo-vp-two-separate-single-channel-lvds.dts | 201 ++++++++++++++++++ .../rk3568-evb1-ddr4-v10-dual-lvds.dts | 14 -- ...-one-vp-two-single-channel-lvds-linux.dts} | 6 +- ...dr4-v10-one-vp-two-single-channel-lvds.dts | 14 ++ ...4-v10-one-vp-two-single-channel-lvds.dtsi} | 36 ++-- ...3568-evb1-ddr4-v10-single-channel-lvds.dts | 133 ++++++++++++ ...wo-vp-two-separate-single-channel-lvds.dts | 198 +++++++++++++++++ 11 files changed, 804 insertions(+), 140 deletions(-) rename arch/arm64/boot/dts/rockchip/{rk3567-evb2-lp4x-v10-dual-lvds.dts => rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts} (90%) create mode 100644 arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts create mode 100644 arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts delete mode 100644 arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dts rename arch/arm64/boot/dts/rockchip/{rk3568-evb1-ddr4-v10-dual-lvds-linux.dts => rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts} (55%) create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts rename arch/arm64/boot/dts/rockchip/{rk3568-evb1-ddr4-v10-dual-lvds.dtsi => rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi} (96%) create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index 3c66f48837c0..88d2ff218476 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile @@ -135,14 +135,18 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-rkg11.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-rk817-tablet-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-channel-lvds.dtb -dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-dual-lvds.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-single-channel-lvds.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-camera.dtb -dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-lvds.dtb -dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-dual-lvds-linux.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux-amp.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-linux-spi-nor.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-single-channel-lvds.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb2-lp4x-v10-bt1120-to-hdmi.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb4-lp3-v10.dtb diff --git a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts index 04043c5d582a..e6972db42c85 100644 --- a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts +++ b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-channel-lvds.dts @@ -70,68 +70,14 @@ }; }; -&backlight1 { - status = "okay"; -}; - &backlight { status = "okay"; }; -&lvds { - status = "okay"; - dual-channel; - - ports { - port@1 { - reg = <1>; - lvds0_out_panel: endpoint { - remote-endpoint = <&panel_in_lvds0>; - }; - }; - }; -}; - -&lvds1 { - status = "okay"; - - ports { - port@1 { - reg = <1>; - lvds1_out_panel: endpoint { - remote-endpoint = <&panel_in_lvds1>; - }; - }; - }; -}; - -&lvds_in_vp1 { +&backlight1 { status = "okay"; }; -&lvds1_in_vp1 { - status = "disabled"; -}; - -&lvds1_in_vp2 { - status = "okay"; -}; - -/* enable hdmi */ -&hdmi_in_vp1 { - status = "okay"; -}; - -/* enable video phy */ -&video_phy0 { - status = "okay"; -}; - -&video_phy1 { - status = "okay"; -}; - -/* disable other encoder output */ &dsi0 { status = "disabled"; }; @@ -152,10 +98,52 @@ status = "disabled"; }; -&rgb_in_vp2 { +&hdmi_in_vp1 { + status = "okay"; +}; + +&lvds0 { + status = "okay"; + dual-channel; + + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds0_in_vp1 { + status = "okay"; +}; + +&lvds1 { + status = "okay"; + + ports { + port@1 { + reg = <1>; + lvds1_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds1>; + }; + }; + }; +}; + +&lvds1_in_vp1 { + status = "okay"; +}; + +&lvds1_in_vp2 { status = "disabled"; }; +&rgb_in_vp2 { + status = "disabled"; +}; &vcc3v3_lcd0_n { gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; @@ -166,3 +154,11 @@ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts similarity index 90% rename from arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts rename to arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts index c4516902c9cc..30f9109242a5 100644 --- a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-dual-lvds.dts +++ b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds.dts @@ -13,8 +13,8 @@ #include "rk3568-android.dtsi" / { - model = "Rockchip RK3567 EVB2 LP4X V10 Board"; - compatible = "rockchip,rk3567-evb2-lp4x-v10", "rockchip,rk3567"; + model = "Rockchip RK3567 EVB2 LP4X V10 Board with one vp two single channel lvds"; + compatible = "rockchip,rk3567-evb2-lp4x-v10-one-vp-two-single-channel-lvds", "rockchip,rk3567"; /* panel: claa070wp03xg */ panel { @@ -34,7 +34,7 @@ timing0: timing0 { clock-frequency = <134000000>; - hactive = <1600>; + hactive = <1600>; /* each panel show 1600 / 2 = 800 pxiel */ vactive = <1280>; hback-porch = <60>; hfront-porch = <60>; @@ -75,15 +75,39 @@ }; }; -&backlight1 { - status = "okay"; -}; - &backlight { status = "okay"; }; -&lvds { +&backlight1 { + status = "okay"; +}; + +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&hdmi_in_vp1 { + status = "okay"; +}; + +&lvds0 { status = "okay"; dual-channel; @@ -110,50 +134,15 @@ }; }; -&lvds_in_vp1 { +&lvds0_in_vp1 { status = "okay"; }; &lvds1_in_vp1 { - status = "disabled"; + status = "okay"; }; &lvds1_in_vp2 { - status = "okay"; -}; - -/* enable hdmi */ -&hdmi_in_vp1 { - status = "okay"; -}; - -/* enable video phy */ -&video_phy0 { - status = "okay"; -}; - -&video_phy1 { - status = "okay"; -}; - -/* disable other encoder output */ -&dsi0 { - status = "disabled"; -}; - -&dsi0_in_vp0 { - status = "disabled"; -}; - -&dsi0_in_vp1 { - status = "disabled"; -}; - -&dsi1_in_vp1 { - status = "disabled"; -}; - -&edp_in_vp1 { status = "disabled"; }; @@ -161,7 +150,6 @@ status = "disabled"; }; - &vcc3v3_lcd0_n { gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; enable-active-high; @@ -171,3 +159,11 @@ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts new file mode 100644 index 000000000000..85621d529671 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-single-channel-lvds.dts @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include +#include +#include + +#include "rk3567-evb2-lp4x-v10.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3567 EVB2 LP4X V10 Board with single channel lvds"; + compatible = "rockchip,rk3567-evb2-lp4x-v10-single-channel-lvds", "rockchip,rk3567"; + + /* panel: claa070wp03xg */ + panel { + compatible = "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd0_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <67000000>; + hactive = <800>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out_panel>; + }; + }; + }; + }; +}; + +&backlight { + status = "okay"; +}; + +&backlight1 { + status = "okay"; +}; + +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&hdmi_in_vp1 { + status = "okay"; +}; + +&lvds0 { + status = "okay"; + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds0_in_vp1 { + status = "okay"; +}; + +&lvds1 { + status = "disabled"; +}; + +&rgb_in_vp2 { + status = "disabled"; +}; + +&vcc3v3_lcd0_n { + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&vcc3v3_lcd1_n { + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts new file mode 100644 index 000000000000..9f3e37e9ec28 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds.dts @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include +#include +#include + +#include "rk3567-evb2-lp4x-v10.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3567 EVB2 LP4X V10 Board with two vp two separate single channel lvds"; + compatible = "rockchip,rk3567-evb2-lp4x-v10-two-vp-two-separate-single-channel-lvds", "rockchip,rk3567"; + + /** + * VP1 -> LVDS0 -> Panel0 + * VP2 -> LVDS1 -> Panel1 + */ + + /* panel: claa070wp03xg */ + panel-lvds0 { + compatible = "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd0_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <67000000>; + hactive = <800>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out_panel>; + }; + }; + }; + }; + + /* panel: claa070wp03xg */ + panel-lvds1 { + compatible = "simple-panel"; + backlight = <&backlight1>; + power-supply = <&vcc3v3_lcd1_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing1>; + timing1: timing1 { + clock-frequency = <67000000>; + hactive = <800>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + panel_in_lvds1: endpoint { + remote-endpoint = <&lvds1_out_panel>; + }; + }; + }; + }; +}; + +&backlight { + status = "okay"; +}; + +&backlight1 { + status = "okay"; +}; + +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&hdmi_in_vp1 { + status = "okay"; +}; + +&lvds0 { + status = "okay"; + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds0_in_vp1 { + status = "okay"; +}; + +&lvds1 { + status = "okay"; + ports { + port@1 { + reg = <1>; + lvds1_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds1>; + }; + }; + }; +}; + +&lvds1_in_vp1 { + status = "disabled"; +}; + +&lvds1_in_vp2 { + status = "okay"; +}; + +&rgb_in_vp2 { + status = "disabled"; +}; + +&vcc3v3_lcd0_n { + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&vcc3v3_lcd1_n { + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dts deleted file mode 100644 index 8cff3652b8d1..000000000000 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dts +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/* - * Copyright (c) 2023 Rockchip Electronics Co., Ltd. - */ - -/dts-v1/; - -#include "rk3568-evb1-ddr4-v10-dual-lvds.dtsi" -#include "rk3568-android.dtsi" - -/ { - model = "Rockchip RK3568 EVB1 V10 Board with Dual LVDS"; - compatible = "rockchip,rk3568-evb1-ddr4-v10-dual-lvds", "rockchip,rk3568"; -}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds-linux.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts similarity index 55% rename from arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds-linux.dts rename to arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts index 6a15126ee392..fb33ac53f9dc 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds-linux.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds-linux.dts @@ -6,12 +6,12 @@ /dts-v1/; #include -#include "rk3568-evb1-ddr4-v10-dual-lvds.dtsi" +#include "rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi" #include "rk3568-linux.dtsi" / { - model = "Rockchip RK3568 EVB1 V10 Board with Dual LVDS"; - compatible = "rockchip,rk3568-evb1-ddr4-v10-dual-lvds", "rockchip,rk3568"; + model = "Rockchip RK3568 EVB1 V10 Board with one vp two single channel lvds"; + compatible = "rockchip,rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds", "rockchip,rk3568"; }; &vp0 { diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts new file mode 100644 index 000000000000..43b0df32cb4b --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dts @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +/dts-v1/; + +#include "rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3568 EVB1 V10 Board with one vp two single channel lvds"; + compatible = "rockchip,rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds", "rockchip,rk3568"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi similarity index 96% rename from arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dtsi rename to arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi index eae796d48b58..51e1d19b99a8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-dual-lvds.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-one-vp-two-single-channel-lvds.dtsi @@ -27,7 +27,7 @@ timing0: timing0 { clock-frequency = <134000000>; - hactive = <1600>; + hactive = <1600>; /* each panel show 1600 / 2 = 800 pxiel */ vactive = <1280>; hback-porch = <60>; hfront-porch = <60>; @@ -68,11 +68,11 @@ }; }; -&backlight1 { +&backlight { status = "okay"; }; -&backlight { +&backlight1 { status = "okay"; }; @@ -100,7 +100,7 @@ status = "okay"; }; -&lvds { +&lvds0 { status = "okay"; dual-channel; @@ -114,6 +114,10 @@ }; }; +&lvds0_in_vp1 { + status = "okay"; +}; + &lvds1 { status = "okay"; @@ -127,30 +131,18 @@ }; }; -&lvds_in_vp1 { - status = "okay"; -}; - &lvds1_in_vp1 { - status = "disabled"; + status = "okay"; }; &lvds1_in_vp2 { - status = "okay"; + status = "disabled"; }; &rgb_in_vp2 { status = "disabled"; }; -&video_phy0 { - status = "okay"; -}; - -&video_phy1 { - status = "okay"; -}; - &vcc3v3_lcd0_n { gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; enable-active-high; @@ -160,3 +152,11 @@ gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; enable-active-high; }; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts new file mode 100644 index 000000000000..e0f543a01c2a --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-single-channel-lvds.dts @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include "rk3568-evb1-ddr4-v10.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3568 EVB1 V10 Board with single channel lvds"; + compatible = "rockchip,rk3568-evb1-ddr4-v10-single-channel-lvds", "rockchip,rk3568"; + + /* panel: claa070wp03xg */ + panel-lvds0 { + compatible = "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd0_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <67000000>; + hactive = <800>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out_panel>; + }; + }; + }; + }; +}; + +&backlight { + status = "okay"; +}; + +&backlight1 { + status = "okay"; +}; + +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&hdmi_in_vp1 { + status = "okay"; +}; + +&lvds0 { + status = "okay"; + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds0_in_vp1 { + status = "okay"; +}; + +&lvds1 { + status = "disabled"; +}; + +&rgb_in_vp2 { + status = "disabled"; +}; + +&vcc3v3_lcd0_n { + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&vcc3v3_lcd1_n { + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts new file mode 100644 index 000000000000..13d0f9127995 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds.dts @@ -0,0 +1,198 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include "rk3568-evb1-ddr4-v10.dtsi" +#include "rk3568-android.dtsi" + +/ { + model = "Rockchip RK3568 EVB1 V10 Board with two vp two separate single channel lvds"; + compatible = "rockchip,rk3568-evb1-ddr4-v10-two-vp-two-separate-single-channel-lvds", "rockchip,rk3568"; + + /** + * VP1 -> LVDS0 -> Panel0 + * VP2 -> LVDS1 -> Panel1 + */ + + /* panel: claa070wp03xg */ + panel-lvds0 { + compatible = "simple-panel"; + backlight = <&backlight>; + power-supply = <&vcc3v3_lcd0_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing0>; + timing0: timing0 { + clock-frequency = <67000000>; + hactive = <800>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + panel_in_lvds0: endpoint { + remote-endpoint = <&lvds0_out_panel>; + }; + }; + }; + }; + + /* panel: claa070wp03xg */ + panel-lvds1 { + compatible = "simple-panel"; + backlight = <&backlight1>; + power-supply = <&vcc3v3_lcd1_n>; + enable-delay-ms = <20>; + prepare-delay-ms = <20>; + unprepare-delay-ms = <20>; + disable-delay-ms = <20>; + bus-format = ; + width-mm = <217>; + height-mm = <136>; + + display-timings { + native-mode = <&timing1>; + timing1: timing1 { + clock-frequency = <67000000>; + hactive = <800>; + vactive = <1280>; + hback-porch = <60>; + hfront-porch = <60>; + vback-porch = <4>; + vfront-porch = <2>; + hsync-len = <8>; + vsync-len = <8>; + hsync-active = <0>; + vsync-active = <0>; + de-active = <0>; + pixelclk-active = <0>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + panel_in_lvds1: endpoint { + remote-endpoint = <&lvds1_out_panel>; + }; + }; + }; + }; +}; + +&backlight { + status = "okay"; +}; + +&backlight1 { + status = "okay"; +}; + +&dsi0 { + status = "disabled"; +}; + +&dsi0_in_vp0 { + status = "disabled"; +}; + +&dsi0_in_vp1 { + status = "disabled"; +}; + +&dsi1_in_vp1 { + status = "disabled"; +}; + +&edp_in_vp1 { + status = "disabled"; +}; + +&hdmi_in_vp1 { + status = "okay"; +}; + +&lvds0 { + status = "okay"; + ports { + port@1 { + reg = <1>; + lvds0_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds0>; + }; + }; + }; +}; + +&lvds0_in_vp1 { + status = "okay"; +}; + +&lvds1 { + status = "okay"; + ports { + port@1 { + reg = <1>; + lvds1_out_panel: endpoint { + remote-endpoint = <&panel_in_lvds1>; + }; + }; + }; +}; + +&lvds1_in_vp1 { + status = "disabled"; +}; + +&lvds1_in_vp2 { + status = "okay"; +}; + +&rgb_in_vp2 { + status = "disabled"; +}; + +&vcc3v3_lcd0_n { + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&vcc3v3_lcd1_n { + gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + enable-active-high; +}; + +&video_phy0 { + status = "okay"; +}; + +&video_phy1 { + status = "okay"; +}; From f4b096ab2d5df4c04b4de123c0ded28ca72a3fe9 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Wed, 22 Nov 2023 10:39:40 +0800 Subject: [PATCH 02/20] phy: rockchip: naneng-combphy: Add phy_validate support Signed-off-by: Shawn Lin Change-Id: Icc2587edadcb37be0bac41c2128391f7583bc3ff --- .../rockchip/phy-rockchip-naneng-combphy.c | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index 3e8e4363e70e..c844328377d9 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -287,9 +287,42 @@ static int rockchip_combphy_exit(struct phy *phy) return 0; } +static const char *rockchip_combphy_mode2str(enum phy_mode mode) +{ + switch (mode) { + case PHY_TYPE_SATA: + return "SATA"; + case PHY_TYPE_PCIE: + return "PCIe"; + case PHY_TYPE_USB3: + return "USB3"; + case PHY_TYPE_SGMII: + case PHY_TYPE_QSGMII: + return "GMII"; + default: + return "Unknown"; + } +} + +static int rockchip_combphy_validate(struct phy *phy, enum phy_mode mode, int submode, + union phy_configure_opts *opts) +{ + struct rockchip_combphy_priv *priv = phy_get_drvdata(phy); + + if (mode != priv->mode) { + dev_err(priv->dev, "expected mode is %s, but current mode is %s\n", + rockchip_combphy_mode2str(mode), + rockchip_combphy_mode2str(priv->mode)); + return -EINVAL; + } + + return 0; +} + static const struct phy_ops rochchip_combphy_ops = { .init = rockchip_combphy_init, .exit = rockchip_combphy_exit, + .validate = rockchip_combphy_validate, .owner = THIS_MODULE, }; From 5dc8f0d04ba59e1a1fc0c74ec4a4cdafcf72919d Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Wed, 22 Nov 2023 10:40:14 +0800 Subject: [PATCH 03/20] PCI: rockchip: dw: Validate phy mode in suspend Some PCIe root port uses combophy but combo phy can be used by other type of controllers. If someone enable phy for both of two controllers, it should break the s2r and hard to debug. Validate this kind of bug and cast an error like this: [ 10.698225] naneng-combphy fee20000.phy: expected mode is PCIe, but current mode is USB3 [ 10.698232] rk-pcie fe180000.pcie: PHY is reused by other controller, check the dts! [ 10.698244] PM: dpm_run_callback(): rockchip_dw_pcie_suspend+0x0/0x410 returns -22 [ 10.698266] PM: Device fe180000.pcie failed to suspend async: error -22 [ 10.902134] PM: pm_system_irq_wakeup: 166 triggered fsc_interrupt_int_n Signed-off-by: Shawn Lin Change-Id: Icc65c9d19ef2bcb54bfb3665d4c012f8ac0e710e --- drivers/pci/controller/dwc/pcie-dw-rockchip.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c index b8d86b5f3039..a63896496f15 100644 --- a/drivers/pci/controller/dwc/pcie-dw-rockchip.c +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -8,6 +8,7 @@ * Author: Simon Xue */ +#include #include #include #include @@ -2335,6 +2336,12 @@ static int __maybe_unused rockchip_dw_pcie_suspend(struct device *dev) no_l2: rk_pcie_disable_ltssm(rk_pcie); + ret = phy_validate(rk_pcie->phy, PHY_TYPE_PCIE, 0, NULL); + if (ret && ret != -EOPNOTSUPP) { + dev_err(dev, "PHY is reused by other controller, check the dts!\n"); + return ret; + } + /* make sure assert phy success */ usleep_range(200, 300); From b473fca294b26a7afffcae8444936e24198aab6e Mon Sep 17 00:00:00 2001 From: shengfei Xu Date: Thu, 23 Nov 2023 03:02:22 +0000 Subject: [PATCH 04/20] mfd: rk806: Add RK806 support i2c Signed-off-by: shengfei Xu Change-Id: Ic7a633fe53b3218cbcc2e8a36d214d6c4c865f85 --- drivers/mfd/Kconfig | 8 +++++ drivers/mfd/Makefile | 1 + drivers/mfd/rk806-core.c | 10 +++++-- drivers/mfd/rk806-i2c.c | 62 +++++++++++++++++++++++++++++++++++++++ drivers/mfd/rk806-spi.c | 10 ++----- include/linux/mfd/rk806.h | 4 ++- 6 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 drivers/mfd/rk806-i2c.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index aa1fe3bcf7f6..0ace44230a00 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1188,6 +1188,14 @@ config MFD_RK806 through SPI interface. The device supports multiple sub-devices including interrupts, LDO & DCDC regulators, and onkey. +config MFD_RK806_I2C + tristate "RK806 Power Management chip with I2C" + select MFD_RK806 + select REGMAP_I2C + select REGMAP_IRQ + help + If you say yes here you get support for the RK806 PM chips with I2c interface. + config MFD_RK806_SPI tristate "RK806 Power Management chip with SPI" select MFD_RK806 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 17c722019f32..57f62d328f22 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -227,6 +227,7 @@ obj-$(CONFIG_MFD_RK630) += rk630.o obj-$(CONFIG_MFD_RK630_I2C) += rk630-i2c.o obj-$(CONFIG_MFD_RK630_SPI) += rk630-spi.o obj-$(CONFIG_MFD_RK806) += rk806-core.o +obj-$(CONFIG_MFD_RK806_I2C) += rk806-i2c.o obj-$(CONFIG_MFD_RK806_SPI) += rk806-spi.o obj-$(CONFIG_MFD_RK808) += rk808.o obj-$(CONFIG_MFD_RK1000) += rk1000-core.o diff --git a/drivers/mfd/rk806-core.c b/drivers/mfd/rk806-core.c index 5421ac95578f..1ab83fbf397c 100644 --- a/drivers/mfd/rk806-core.c +++ b/drivers/mfd/rk806-core.c @@ -352,13 +352,13 @@ static const struct regmap_access_table rk806_volatile_table = { .n_yes_ranges = ARRAY_SIZE(rk806_yes_ranges), }; -const struct regmap_config rk806_regmap_config_spi = { +const struct regmap_config rk806_regmap_config = { .reg_bits = 8, .val_bits = 8, .cache_type = REGCACHE_RBTREE, .volatile_table = &rk806_volatile_table, }; -EXPORT_SYMBOL_GPL(rk806_regmap_config_spi); +EXPORT_SYMBOL_GPL(rk806_regmap_config); static struct kobject *rk806_kobj[2]; static struct rk806 *rk806_master; @@ -825,6 +825,12 @@ int rk806_device_exit(struct rk806 *rk806) } EXPORT_SYMBOL_GPL(rk806_device_exit); +const struct of_device_id rk806_of_match[] = { + { .compatible = "rockchip,rk806", }, + { } +}; +EXPORT_SYMBOL_GPL(rk806_of_match); + MODULE_AUTHOR("Xu Shengfei "); MODULE_DESCRIPTION("rk806 MFD Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/rk806-i2c.c b/drivers/mfd/rk806-i2c.c new file mode 100644 index 000000000000..26558e90d1fe --- /dev/null +++ b/drivers/mfd/rk806-i2c.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * rk806-i2c.c -- I2C access for Rockchip RK806 + * + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + * + * Author: Xu Shengfei + */ + +#include +#include +#include + +static int rk806_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct rk806 *rk806; + + rk806 = devm_kzalloc(&client->dev, sizeof(*rk806), GFP_KERNEL); + if (!rk806) + return -ENOMEM; + + i2c_set_clientdata(client, rk806); + rk806->dev = &client->dev; + rk806->irq = client->irq; + + if (!client->irq) { + dev_err(&client->dev, "No interrupt support, no core IRQ\n"); + return -EINVAL; + } + + rk806->regmap = devm_regmap_init_i2c(client, &rk806_regmap_config); + if (IS_ERR(rk806->regmap)) { + dev_err(&client->dev, "regmap initialization failed\n"); + return PTR_ERR(rk806->regmap); + } + + return rk806_device_init(rk806); +} + +static int rk806_remove(struct i2c_client *client) +{ + struct rk806 *rk806 = i2c_get_clientdata(client); + + rk806_device_exit(rk806); + + return 0; +} + +static struct i2c_driver rk806_i2c_driver = { + .driver = { + .name = "rk806", + .of_match_table = of_match_ptr(rk806_of_match), + }, + .probe = rk806_i2c_probe, + .remove = rk806_remove, +}; +module_i2c_driver(rk806_i2c_driver); + +MODULE_AUTHOR("Xu Shengfei "); +MODULE_DESCRIPTION("RK806 I2C Interface Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/rk806-spi.c b/drivers/mfd/rk806-spi.c index 246602417c66..561037865200 100644 --- a/drivers/mfd/rk806-spi.c +++ b/drivers/mfd/rk806-spi.c @@ -12,12 +12,6 @@ #include #include -static const struct of_device_id rk806_spi_of_match_table[] = { - { .compatible = "rockchip,rk806", }, - { } -}; -MODULE_DEVICE_TABLE(of, rk806_spi_of_match_table); - static int rk806_spi_write(struct spi_device *spi, char addr, const char *data, @@ -101,7 +95,7 @@ static int rk806_spi_probe(struct spi_device *spi) rk806->regmap = devm_regmap_init(&spi->dev, &rk806_regmap_bus_spi, &spi->dev, - &rk806_regmap_config_spi); + &rk806_regmap_config); if (IS_ERR(rk806->regmap)) { dev_err(rk806->dev, "Failed to initialize register map\n"); return PTR_ERR(rk806->regmap); @@ -127,7 +121,7 @@ static struct spi_driver rk806_spi_driver = { .driver = { .name = "rk806", .owner = THIS_MODULE, - .of_match_table = rk806_spi_of_match_table, + .of_match_table = of_match_ptr(rk806_of_match), }, .probe = rk806_spi_probe, .remove = rk806_spi_remove, diff --git a/include/linux/mfd/rk806.h b/include/linux/mfd/rk806.h index 71e833c51444..7735121592c8 100644 --- a/include/linux/mfd/rk806.h +++ b/include/linux/mfd/rk806.h @@ -6,6 +6,7 @@ #ifndef __LINUX_REGULATOR_RK806_H #define __LINUX_REGULATOR_RK806_H +#include #include #include #include @@ -518,7 +519,8 @@ struct rk806 { int vb_lo_irq; }; -extern const struct regmap_config rk806_regmap_config_spi; +extern const struct regmap_config rk806_regmap_config; +extern const struct of_device_id rk806_of_match[]; int rk806_device_init(struct rk806 *rk806); int rk806_device_exit(struct rk806 *rk806); int rk806_field_write(struct rk806 *rk806, From d2188d8a064b10f5b62139bf3846c2e253aea8c3 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 24 Nov 2023 15:34:17 +0800 Subject: [PATCH 05/20] media: rockchip: isp: fix wnd_num cause array access out of bounds Change-Id: I689475aacd5e0a49dee067a03c995aee241bcf5b Signed-off-by: Cai YiWei --- .../platform/rockchip/isp/isp_params_v21.c | 18 ++++++++++++++ .../platform/rockchip/isp/isp_params_v2x.c | 24 +++++++++++++++++++ .../platform/rockchip/isp/isp_params_v32.c | 18 ++++++++++++++ .../platform/rockchip/isp/isp_params_v3x.c | 18 ++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/drivers/media/platform/rockchip/isp/isp_params_v21.c b/drivers/media/platform/rockchip/isp/isp_params_v21.c index 6fac6ab466d1..e13e97ca53d0 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v21.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v21.c @@ -1178,6 +1178,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, ISP2X_REG_WR_MASK); wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } value |= ISP2X_RAWAEBIG_WNDNUM_SET(wnd_num_idx); if (arg->subwin_en[0]) @@ -2291,6 +2297,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, return; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } memset(weight15x15, 0, sizeof(weight15x15)); for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) { for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) { @@ -2338,6 +2350,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, } wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } /* avoid to override the old enable value */ hist_ctrl = rkisp_ioread32(params_vdev, addr + ISP_RAWHIST_BIG_CTRL); hist_ctrl &= ISP2X_RAWHSTBIG_CTRL_EN_MASK; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v2x.c b/drivers/media/platform/rockchip/isp/isp_params_v2x.c index 2877ab1d2fd8..c1497a92ffd1 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v2x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v2x.c @@ -461,6 +461,12 @@ isp_sihst_config(struct rkisp_isp_params_vdev *params_vdev, }; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } for (i = 0; i < ISP2X_SIHIST_WIN_NUM; i++) { /* avoid to override the old enable value */ hist_ctrl = rkisp_ioread32(params_vdev, ISP_HIST_HIST_CTRL + i * 0x10); @@ -1758,6 +1764,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, ISP2X_REG_WR_MASK); wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } value |= ISP2X_RAWAEBIG_WNDNUM_SET(wnd_num_idx); if (arg->subwin_en[0]) @@ -2831,6 +2843,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, return; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } memset(weight15x15, 0, sizeof(weight15x15)); for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) { for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) { @@ -2879,6 +2897,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, } wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } /* avoid to override the old enable value */ hist_ctrl = rkisp_ioread32(params_vdev, addr + ISP_RAWHIST_BIG_CTRL); hist_ctrl &= ISP2X_RAWHSTBIG_CTRL_EN_MASK; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v32.c b/drivers/media/platform/rockchip/isp/isp_params_v32.c index 255451cf7fee..ebc0b707b916 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v32.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v32.c @@ -1436,6 +1436,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, value &= ISP3X_RAWAE_BIG_EN; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx); if (arg->subwin_en[0]) @@ -2413,6 +2419,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, return; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } memset(weight15x15, 0, sizeof(weight15x15)); for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) { for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) { @@ -2463,6 +2475,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, } wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } /* avoid to override the old enable value */ hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id); hist_ctrl &= ISP3X_RAWHIST_EN; diff --git a/drivers/media/platform/rockchip/isp/isp_params_v3x.c b/drivers/media/platform/rockchip/isp/isp_params_v3x.c index 2478c09d7062..0491cc9bd8ba 100644 --- a/drivers/media/platform/rockchip/isp/isp_params_v3x.c +++ b/drivers/media/platform/rockchip/isp/isp_params_v3x.c @@ -1291,6 +1291,12 @@ isp_rawaebig_config(struct rkisp_isp_params_vdev *params_vdev, value &= ISP3X_RAWAE_BIG_EN; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(ae_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(ae_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } value |= ISP3X_RAWAE_BIG_WND0_NUM(wnd_num_idx); if (arg->subwin_en[0]) @@ -2424,6 +2430,12 @@ isp_rawhstbig_cfg_sram(struct rkisp_isp_params_vdev *params_vdev, return; wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } memset(weight15x15, 0, sizeof(weight15x15)); for (i = 0; i < hist_wnd_num[wnd_num_idx]; i++) { for (j = 0; j < hist_wnd_num[wnd_num_idx]; j++) { @@ -2471,6 +2483,12 @@ isp_rawhstbig_config(struct rkisp_isp_params_vdev *params_vdev, } wnd_num_idx = arg->wnd_num; + if (wnd_num_idx >= ARRAY_SIZE(hist_wnd_num)) { + wnd_num_idx = ARRAY_SIZE(hist_wnd_num) - 1; + dev_err(params_vdev->dev->dev, + "%s invalid wnd_num:%d, set to %d\n", + __func__, arg->wnd_num, wnd_num_idx); + } /* avoid to override the old enable value */ hist_ctrl = isp3_param_read(params_vdev, addr + ISP3X_RAWHIST_BIG_CTRL, id); hist_ctrl &= ISP3X_RAWHIST_EN; From 5592509ba46c902fd9970b563fb70cbc5116d3a0 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Fri, 10 Nov 2023 12:06:47 +0800 Subject: [PATCH 06/20] misc: rockchip: pcie-rkep: Adding more mmap resources Adding: PCIE_EP_MMAP_RESOURCE_USER_MEM, PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI, PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI, Change-Id: I69facbb8b268516c3ab68f70f15650b214649c55 Signed-off-by: Jon Lin --- include/uapi/linux/rk-pcie-ep.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/uapi/linux/rk-pcie-ep.h b/include/uapi/linux/rk-pcie-ep.h index 89b6c4fa558b..02ec92fcbc27 100644 --- a/include/uapi/linux/rk-pcie-ep.h +++ b/include/uapi/linux/rk-pcie-ep.h @@ -74,6 +74,9 @@ enum pcie_ep_mmap_resource { PCIE_EP_MMAP_RESOURCE_BAR0, PCIE_EP_MMAP_RESOURCE_BAR2, PCIE_EP_MMAP_RESOURCE_BAR4, + PCIE_EP_MMAP_RESOURCE_USER_MEM, + PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI, + PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI, PCIE_EP_MMAP_RESOURCE_MAX, }; From 694b4503a6a0243db13e9dcd6e857cfd5d1aad71 Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Fri, 10 Nov 2023 12:06:03 +0800 Subject: [PATCH 07/20] misc: rockchip: pcie-rkep: Support mmap bar resource and rw config space Change-Id: Ib97bd299cfdc3bcba40250cc1d10686fb1fc64e4 Signed-off-by: Jon Lin --- drivers/misc/rockchip/pcie-rkep.c | 270 ++++++++++++++++++++++++------ include/uapi/linux/rk-pcie-ep.h | 2 +- 2 files changed, 219 insertions(+), 53 deletions(-) diff --git a/drivers/misc/rockchip/pcie-rkep.c b/drivers/misc/rockchip/pcie-rkep.c index 70b0e9eb50c3..cc45f5bf3c32 100644 --- a/drivers/misc/rockchip/pcie-rkep.c +++ b/drivers/misc/rockchip/pcie-rkep.c @@ -91,6 +91,10 @@ static DEFINE_MUTEX(rkep_mutex); #define RKEP_EP_VIRTUAL_ID_MAX (8 * 4096) #define RKEP_EP_ELBI_TIEMOUT_US 100000 +#define PCIE_RK3568_RC_DBI_BASE 0xf6000000 +#define PCIE_RK3588_RC_DBI_BASE 0xf5000000 +#define PCIE_DBI_SIZE 0x400000 + struct pcie_rkep_msix_context { struct pci_dev *dev; u16 msg_id; @@ -102,12 +106,14 @@ struct pcie_rkep { void __iomem *bar0; void __iomem *bar2; void __iomem *bar4; - struct miscdevice dev; + int cur_mmap_res; struct msix_entry msix_entries[RKEP_NUM_MSIX_VECTORS]; struct pcie_rkep_msix_context msix_ctx[RKEP_NUM_MSIX_VECTORS]; struct pcie_rkep_msix_context msi_ctx[RKEP_NUM_MSI_VECTORS]; bool msi_enable; bool msix_enable; + + struct miscdevice dev; struct dma_trx_obj *dma_obj; struct pcie_ep_obj_info *obj_info; struct page *user_pages; /* Allocated physical memory for user space */ @@ -275,33 +281,73 @@ static ssize_t pcie_rkep_write(struct file *file, const char __user *buf, { struct pcie_file *pcie_file = file->private_data; struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; - u32 *bar0_buf; - int loop, i = 0; - size_t raw_count = count; + struct pci_dev *dev = pcie_rkep->pdev; + unsigned int size = count; + loff_t init_off = *ppos, off = *ppos; + u8 *data; - count = (count % 4) ? (count - count % 4) : count; - - if (count > BAR_0_SZ) - return -EINVAL; - - bar0_buf = kzalloc(count, GFP_KERNEL); - if (!bar0_buf) + data = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL); + if (!data) return -ENOMEM; - if (copy_from_user(bar0_buf, buf, count)) { - raw_count = -EFAULT; - goto exit; + if (off > dev->cfg_size) { + kfree(data); + return 0; + } + if (off + count > dev->cfg_size) { + size = dev->cfg_size - off; + count = size; } - for (loop = 0; loop < count / 4; loop++) { - iowrite32(bar0_buf[i], pcie_rkep->bar0 + loop * 4); - i++; + if (copy_from_user(data, buf, count)) { + kfree(data); + return -EFAULT; } -exit: - kfree(bar0_buf); + if ((off & 1) && size) { + pci_write_config_byte(dev, off, data[off - init_off]); + off++; + size--; + } - return raw_count; + if ((off & 3) && size > 2) { + u16 val = data[off - init_off]; + + val |= (u16) data[off - init_off + 1] << 8; + pci_write_config_word(dev, off, val); + off += 2; + size -= 2; + } + + while (size > 3) { + u32 val = data[off - init_off]; + + val |= (u32) data[off - init_off + 1] << 8; + val |= (u32) data[off - init_off + 2] << 16; + val |= (u32) data[off - init_off + 3] << 24; + pci_write_config_dword(dev, off, val); + off += 4; + size -= 4; + } + + if (size >= 2) { + u16 val = data[off - init_off]; + + val |= (u16) data[off - init_off + 1] << 8; + pci_write_config_word(dev, off, val); + off += 2; + size -= 2; + } + + if (size) { + pci_write_config_byte(dev, off, data[off - init_off]); + off++; + --size; + } + + kfree(data); + + return count; } static ssize_t pcie_rkep_read(struct file *file, char __user *buf, @@ -309,33 +355,82 @@ static ssize_t pcie_rkep_read(struct file *file, char __user *buf, { struct pcie_file *pcie_file = file->private_data; struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; - u32 *bar0_buf; - int loop, i = 0; - size_t raw_count = count; + struct pci_dev *dev = pcie_rkep->pdev; + unsigned int size = count; + loff_t init_off = *ppos, off = *ppos; + u8 *data; - count = (count % 4) ? (count - count % 4) : count; - - if (count > BAR_0_SZ) - return -EINVAL; - - bar0_buf = kzalloc(count, GFP_ATOMIC); - if (!bar0_buf) + data = kzalloc(PCI_CFG_SPACE_EXP_SIZE, GFP_KERNEL); + if (!data) return -ENOMEM; - for (loop = 0; loop < count / 4; loop++) { - bar0_buf[i] = ioread32(pcie_rkep->bar0 + loop * 4); - i++; + if (off > dev->cfg_size) { + kfree(data); + return 0; + } + if (off + count > dev->cfg_size) { + size = dev->cfg_size - off; + count = size; } - if (copy_to_user(buf, bar0_buf, count)) { - raw_count = -EFAULT; - goto exit; + if ((off & 1) && size) { + u8 val; + + pci_read_config_byte(dev, off, &val); + data[off - init_off] = val; + off++; + size--; } -exit: - kfree(bar0_buf); + if ((off & 3) && size > 2) { + u16 val; - return raw_count; + pci_read_config_word(dev, off, &val); + data[off - init_off] = val & 0xff; + data[off - init_off + 1] = (val >> 8) & 0xff; + off += 2; + size -= 2; + } + + while (size > 3) { + u32 val; + + pci_read_config_dword(dev, off, &val); + data[off - init_off] = val & 0xff; + data[off - init_off + 1] = (val >> 8) & 0xff; + data[off - init_off + 2] = (val >> 16) & 0xff; + data[off - init_off + 3] = (val >> 24) & 0xff; + off += 4; + size -= 4; + } + + if (size >= 2) { + u16 val; + + pci_read_config_word(dev, off, &val); + data[off - init_off] = val & 0xff; + data[off - init_off + 1] = (val >> 8) & 0xff; + off += 2; + size -= 2; + } + + if (size > 0) { + u8 val; + + pci_read_config_byte(dev, off, &val); + data[off - init_off] = val; + off++; + --size; + } + + if (copy_to_user(buf, data, count)) { + kfree(data); + return -EFAULT; + } + + kfree(data); + + return count; } static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma) @@ -343,26 +438,81 @@ static int pcie_rkep_mmap(struct file *file, struct vm_area_struct *vma) u64 addr; struct pcie_file *pcie_file = file->private_data; struct pcie_rkep *pcie_rkep = pcie_file->pcie_rkep; + struct pci_dev *dev = pcie_rkep->pdev; size_t size = vma->vm_end - vma->vm_start; + resource_size_t bar_size; + int err; - if (size > RKEP_USER_MEM_SIZE) { - dev_warn(&pcie_rkep->pdev->dev, "mmap size is out of limitation\n"); + switch (pcie_rkep->cur_mmap_res) { + case PCIE_EP_MMAP_RESOURCE_RK3568_RC_DBI: + if (size > PCIE_DBI_SIZE) { + dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n"); + return -EINVAL; + } + addr = PCIE_RK3568_RC_DBI_BASE; + break; + case PCIE_EP_MMAP_RESOURCE_RK3588_RC_DBI: + if (size > PCIE_DBI_SIZE) { + dev_warn(&pcie_rkep->pdev->dev, "dbi mmap size is out of limitation\n"); + return -EINVAL; + } + addr = PCIE_RK3588_RC_DBI_BASE; + break; + case PCIE_EP_MMAP_RESOURCE_BAR0: + bar_size = pci_resource_len(dev, 0); + if (size > bar_size) { + dev_warn(&pcie_rkep->pdev->dev, "bar0 mmap size is out of limitation\n"); + return -EINVAL; + } + addr = pci_resource_start(dev, 0); + break; + case PCIE_EP_MMAP_RESOURCE_BAR2: + bar_size = pci_resource_len(dev, 2); + if (size > bar_size) { + dev_warn(&pcie_rkep->pdev->dev, "bar2 mmap size is out of limitation\n"); + return -EINVAL; + } + addr = pci_resource_start(dev, 2); + break; + case PCIE_EP_MMAP_RESOURCE_BAR4: + bar_size = pci_resource_len(dev, 4); + if (size > bar_size) { + dev_warn(&pcie_rkep->pdev->dev, "bar4 mmap size is out of limitation\n"); + return -EINVAL; + } + addr = pci_resource_start(dev, 4); + break; + case PCIE_EP_MMAP_RESOURCE_USER_MEM: + if (size > RKEP_USER_MEM_SIZE) { + dev_warn(&pcie_rkep->pdev->dev, "mmap size is out of limitation\n"); + return -EINVAL; + } + + if (!pcie_rkep->user_pages) { + dev_warn(&pcie_rkep->pdev->dev, "user_pages has not been allocated yet\n"); + return -EINVAL; + } + addr = page_to_phys(pcie_rkep->user_pages); + break; + default: + dev_err(&pcie_rkep->pdev->dev, "cur mmap_res %d is unsurreport\n", pcie_rkep->cur_mmap_res); return -EINVAL; } - if (!pcie_rkep->user_pages) { - dev_warn(&pcie_rkep->pdev->dev, "user_pages has not been allocated yet\n"); - return -EINVAL; - } - - addr = page_to_phys(pcie_rkep->user_pages); vma->vm_flags |= VM_IO; - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP); - if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, size, vma->vm_page_prot)) { - dev_err(&pcie_rkep->pdev->dev, "io_remap_pfn_range failed\n"); + if (pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_BAR2 || + pcie_rkep->cur_mmap_res == PCIE_EP_MMAP_RESOURCE_USER_MEM) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + else + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + err = remap_pfn_range(vma, vma->vm_start, + __phys_to_pfn(addr), + size, vma->vm_page_prot); + if (err) return -EAGAIN; - } return 0; } @@ -375,6 +525,7 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a struct pcie_ep_dma_cache_cfg cfg; struct pcie_ep_dma_block_req dma; void __user *uarg = (void __user *)args; + int mmap_res; int ret; int index; u64 addr; @@ -462,6 +613,20 @@ static long pcie_rkep_ioctl(struct file *file, unsigned int cmd, unsigned long a return -EFAULT; } break; + case PCIE_EP_SET_MMAP_RESOURCE: + ret = copy_from_user(&mmap_res, uarg, sizeof(mmap_res)); + if (ret) { + dev_err(&pcie_rkep->pdev->dev, "failed to get copy from\n"); + return -EFAULT; + } + + if (mmap_res >= PCIE_EP_MMAP_RESOURCE_MAX || mmap_res < 0) { + dev_err(&pcie_rkep->pdev->dev, "mmap index %d is out of number\n", mmap_res); + return -EINVAL; + } + + pcie_rkep->cur_mmap_res = mmap_res; + break; default: break; } @@ -478,7 +643,7 @@ static const struct file_operations pcie_rkep_fops = { .mmap = pcie_rkep_mmap, .fasync = pcie_rkep_fasync, .release = pcie_rkep_release, - .llseek = no_llseek, + .llseek = default_llseek, }; static inline void pcie_rkep_writel_dbi(struct pcie_rkep *pcie_rkep, u32 reg, u32 val) @@ -985,6 +1150,7 @@ static int pcie_rkep_probe(struct pci_dev *pdev, const struct pci_device_id *id) pcie_dw_dmatest_unregister(pcie_rkep->dma_obj); goto err_register_obj; } + pcie_rkep->cur_mmap_res = PCIE_EP_MMAP_RESOURCE_USER_MEM; dev_err(&pdev->dev, "successfully allocate continuouse buffer for userspace\n"); #endif diff --git a/include/uapi/linux/rk-pcie-ep.h b/include/uapi/linux/rk-pcie-ep.h index 02ec92fcbc27..b60130fd63af 100644 --- a/include/uapi/linux/rk-pcie-ep.h +++ b/include/uapi/linux/rk-pcie-ep.h @@ -106,7 +106,7 @@ struct pcie_ep_obj_info { #define PCIE_DMA_IRQ_MASK_ALL _IOW(PCIE_BASE, 3, int) #define PCIE_DMA_RAISE_MSI_OBJ_IRQ_USER _IOW(PCIE_BASE, 4, int) #define PCIE_EP_GET_USER_INFO _IOR(PCIE_BASE, 5, struct pcie_ep_user_data) -#define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 6, enum pcie_ep_mmap_resource) +#define PCIE_EP_SET_MMAP_RESOURCE _IOW(PCIE_BASE, 6, int) #define PCIE_EP_RAISE_ELBI _IOW(PCIE_BASE, 7, int) #define PCIE_EP_REQUEST_VIRTUAL_ID _IOR(PCIE_BASE, 16, int) #define PCIE_EP_RELEASE_VIRTUAL_ID _IOW(PCIE_BASE, 17, int) From 7d15f43d9188d2fe1c0730ed0b45f48ee16b3d4d Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Sat, 11 Nov 2023 22:55:30 +0800 Subject: [PATCH 08/20] PCI: rockchip: dw: Reserve msi_data in obj_info Change-Id: I7b589d6c5b03a96c04c33330c63066505dabc1b0 Signed-off-by: Jon Lin --- include/uapi/linux/rk-pcie-ep.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/rk-pcie-ep.h b/include/uapi/linux/rk-pcie-ep.h index b60130fd63af..345c6c2e9e86 100644 --- a/include/uapi/linux/rk-pcie-ep.h +++ b/include/uapi/linux/rk-pcie-ep.h @@ -90,7 +90,8 @@ struct pcie_ep_obj_info { __u16 mode; __u16 submode; } devmode; - __u8 reserved[0x1F4]; + __u32 msi_data[0x8]; + __u8 reserved[0x1D4]; __u32 irq_type_rc; /* Generate in ep isr, valid only for rc, clear in rc */ struct pcie_ep_obj_irq_dma_status dma_status_rc; /* Generate in ep isr, valid only for rc, clear in rc */ From 23789ce8693760b285cdcff7bccfe47b928372dd Mon Sep 17 00:00:00 2001 From: Damon Ding Date: Mon, 12 Jun 2023 10:33:39 +0800 Subject: [PATCH 09/20] arm64: dts: rockchip: px30: add pwm irq configs Signed-off-by: Damon Ding Change-Id: I121376bf28c157d5d588466dc9d5796e764cd425 --- arch/arm64/boot/dts/rockchip/px30.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 6a0be2418d81..acf496b140ca 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -1045,6 +1045,7 @@ pwm0: pwm@ff200000 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff200000 0x0 0x10>; + interrupts = ; clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1056,6 +1057,7 @@ pwm1: pwm@ff200010 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff200010 0x0 0x10>; + interrupts = ; clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1067,6 +1069,7 @@ pwm2: pwm@ff200020 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff200020 0x0 0x10>; + interrupts = ; clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1078,6 +1081,8 @@ pwm3: pwm@ff200030 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff200030 0x0 0x10>; + interrupts = , + ; clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1089,6 +1094,7 @@ pwm4: pwm@ff208000 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff208000 0x0 0x10>; + interrupts = ; clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1100,6 +1106,7 @@ pwm5: pwm@ff208010 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff208010 0x0 0x10>; + interrupts = ; clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1111,6 +1118,7 @@ pwm6: pwm@ff208020 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff208020 0x0 0x10>; + interrupts = ; clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; @@ -1122,6 +1130,8 @@ pwm7: pwm@ff208030 { compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm"; reg = <0x0 0xff208030 0x0 0x10>; + interrupts = , + ; clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>; clock-names = "pwm", "pclk"; pinctrl-names = "active"; From 86d8a7fc28a47b03f20915c62f2d122274bb0fa5 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Thu, 19 Oct 2023 21:21:31 +0800 Subject: [PATCH 10/20] soc: rockchip: Add clock subunit driver Signed-off-by: Finley Xiao Change-Id: Id1d784d2549bf1c47066b572d32b396966c52c96 --- drivers/soc/rockchip/Kconfig | 6 + drivers/soc/rockchip/Makefile | 1 + drivers/soc/rockchip/rockchip_csu.c | 377 +++++++++++++++++++++++++ include/dt-bindings/soc/rockchip-csu.h | 15 + include/soc/rockchip/rockchip_csu.h | 46 +++ 5 files changed, 445 insertions(+) create mode 100644 drivers/soc/rockchip/rockchip_csu.c create mode 100644 include/dt-bindings/soc/rockchip-csu.h create mode 100644 include/soc/rockchip/rockchip_csu.h diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig index e618feca7697..82ddb8324eb6 100644 --- a/drivers/soc/rockchip/Kconfig +++ b/drivers/soc/rockchip/Kconfig @@ -44,6 +44,12 @@ config ROCKCHIP_CPUINFO If unsure, say N. +config ROCKCHIP_CSU + tristate "Rockchip Clock Subunit Driver" + depends on ARCH_ROCKCHIP + help + This adds the clock subunit driver for Rockchip SoCs. + config ROCKCHIP_GRF tristate "Rockchip General Register Files support" help diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile index c4b5c8a5cbd3..d9bd4bf616e8 100644 --- a/drivers/soc/rockchip/Makefile +++ b/drivers/soc/rockchip/Makefile @@ -4,6 +4,7 @@ # obj-$(CONFIG_ROCKCHIP_AMP) += rockchip_amp.o obj-$(CONFIG_ROCKCHIP_CPUINFO) += rockchip-cpuinfo.o +obj-$(CONFIG_ROCKCHIP_CSU) += rockchip_csu.o obj-$(CONFIG_ROCKCHIP_GRF) += grf.o obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS) += rockchip_decompress.o obj-$(CONFIG_ROCKCHIP_HW_DECOMPRESS_USER) += rockchip_decompress_user.o diff --git a/drivers/soc/rockchip/rockchip_csu.c b/drivers/soc/rockchip/rockchip_csu.c new file mode 100644 index 000000000000..04a6a5b39715 --- /dev/null +++ b/drivers/soc/rockchip/rockchip_csu.c @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2023, Rockchip Electronics Co., Ltd. + * Author: Finley Xiao + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct csu_bus { + unsigned int id; + unsigned int cfg_val; + unsigned int en_mask; + unsigned int disable_count; +}; + +struct csu_clk { + unsigned int clk_id; + unsigned int bus_id; +}; + +struct rockchip_csu { + struct device *dev; + struct csu_bus *bus; + struct csu_clk *clk; + unsigned int bus_cnt; + unsigned int clk_cnt; +}; + +static struct rockchip_csu *rk_csu; +static DEFINE_MUTEX(csu_lock); + +static int rockchip_csu_sip_config(struct device *dev, u32 bus_id, u32 cfg, + u32 enable_msk) +{ + struct arm_smccc_res res; + + dev_dbg(dev, "id=%u, cfg=0x%x, en_mask=0x%x\n", bus_id, cfg, enable_msk); + res = sip_smc_bus_config(bus_id, cfg, enable_msk); + + return res.a0; +} + +struct csu_clk *rockchip_csu_get(struct device *dev, const char *name) +{ + struct of_phandle_args args; + struct csu_clk *clk = ERR_PTR(-ENOENT); + unsigned int clk_id = 0; + int index = 0, i = 0; + + if (!dev || !dev->of_node) + return ERR_PTR(-ENODEV); + if (!rk_csu || !rk_csu->bus || !rk_csu->clk) + return ERR_PTR(-ENODEV); + + if (name) + index = of_property_match_string(dev->of_node, + "rockchip,csu-names", + name); + if (of_parse_phandle_with_fixed_args(dev->of_node, "rockchip,csu", 1, + index, &args)) { + dev_err(dev, "Missing the phandle args name %s\n", name); + return ERR_PTR(-ENODEV); + } + clk_id = args.args[0]; + + for (i = 0; i < rk_csu->clk_cnt; i++) { + if (clk_id == rk_csu->clk[i].clk_id) { + clk = &rk_csu->clk[i]; + break; + } + } + + return clk; +} +EXPORT_SYMBOL(rockchip_csu_get); + +static int csu_disable(struct csu_clk *clk, bool disable) +{ + struct csu_bus *bus = NULL; + unsigned int en_mask = 0; + int ret = 0; + + if (IS_ERR_OR_NULL(clk)) + return 0; + if (clk->bus_id >= rk_csu->bus_cnt) + return 0; + bus = &rk_csu->bus[clk->bus_id]; + if (!bus) + return 0; + + mutex_lock(&csu_lock); + + if (disable) + bus->disable_count++; + else if (bus->disable_count > 0) + bus->disable_count--; + + if (bus->disable_count) + en_mask = bus->en_mask & CSU_EN_MASK; + else + en_mask = bus->en_mask; + + ret = rockchip_csu_sip_config(rk_csu->dev, bus->id, bus->cfg_val, en_mask); + if (ret) + dev_err(rk_csu->dev, "csu sip config disable error\n"); + + mutex_unlock(&csu_lock); + + return ret; +} + +int rockchip_csu_enable(struct csu_clk *clk) +{ + return csu_disable(clk, false); +} +EXPORT_SYMBOL(rockchip_csu_enable); + +int rockchip_csu_disable(struct csu_clk *clk) +{ + return csu_disable(clk, true); +} +EXPORT_SYMBOL(rockchip_csu_disable); + +int rockchip_csu_set_div(struct csu_clk *clk, unsigned int div) +{ + struct csu_bus *bus = NULL; + unsigned int cfg_val = 0; + int ret = 0; + + if (IS_ERR_OR_NULL(clk)) + return 0; + if (clk->bus_id >= rk_csu->bus_cnt) + return 0; + bus = &rk_csu->bus[clk->bus_id]; + if (!bus) + return 0; + + mutex_lock(&csu_lock); + + if (div > CSU_MAX_DIV) + div = CSU_MAX_DIV; + cfg_val = (bus->cfg_val & ~CSU_DIV_MASK) | ((div - 1) & CSU_DIV_MASK); + + ret = rockchip_csu_sip_config(rk_csu->dev, bus->id, cfg_val, bus->en_mask); + if (ret) + dev_err(rk_csu->dev, "csu sip config freq error\n"); + + mutex_unlock(&csu_lock); + + return ret; +} +EXPORT_SYMBOL(rockchip_csu_set_div); + +static int rockchip_csu_parse_clk(struct rockchip_csu *csu) +{ + struct device *dev = csu->dev; + struct device_node *np = dev->of_node; + char *prop_name = "rockchip,clock"; + struct csu_clk *tmp; + const struct property *prop; + int count, i; + + prop = of_find_property(np, prop_name, NULL); + if (!prop) + return -EINVAL; + + if (!prop->value) + return -ENODATA; + + count = of_property_count_u32_elems(np, prop_name); + if (count < 0) + return -EINVAL; + + if (count % 2) + return -EINVAL; + + tmp = devm_kcalloc(dev, count / 2, sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + for (i = 0; i < count / 2; i++) { + of_property_read_u32_index(np, prop_name, 2 * i, + &tmp[i].clk_id); + of_property_read_u32_index(np, prop_name, 2 * i + 1, + &tmp[i].bus_id); + } + + csu->clk = tmp; + csu->clk_cnt = count / 2; + + return 0; +} + +static int rockchip_csu_parse_bus_table(struct rockchip_csu *csu) +{ + struct device *dev = csu->dev; + struct device_node *np = dev->of_node; + char *prop_name = "rockchip,bus"; + struct csu_bus *tmp; + const struct property *prop; + int count, i; + + prop = of_find_property(np, prop_name, NULL); + if (!prop) + return -EINVAL; + + if (!prop->value) + return -ENODATA; + + count = of_property_count_u32_elems(np, prop_name); + if (count < 0) + return -EINVAL; + + if (count % 3) + return -EINVAL; + + tmp = devm_kcalloc(dev, count / 3, sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + for (i = 0; i < count / 3; i++) { + of_property_read_u32_index(np, prop_name, 3 * i, + &tmp[i].id); + of_property_read_u32_index(np, prop_name, 3 * i + 1, + &tmp[i].cfg_val); + of_property_read_u32_index(np, prop_name, 3 * i + 2, + &tmp[i].en_mask); + } + + csu->bus = tmp; + csu->bus_cnt = count / 3; + + return 0; +} + +static int rockchip_csu_bus_table(struct rockchip_csu *csu) +{ + struct device *dev = csu->dev; + struct csu_bus *bus; + int i; + + if (rockchip_csu_parse_bus_table(csu)) + return -EINVAL; + + for (i = 0; i < csu->bus_cnt; i++) { + bus = &csu->bus[i]; + if (!bus || !bus->cfg_val) { + dev_info(dev, "bus %d cfg-val invalid\n", i); + continue; + } + if (rockchip_csu_sip_config(dev, bus->id, bus->cfg_val, bus->en_mask)) + dev_err(dev, "csu sip config error\n"); + } + + return 0; +} + +static int rockchip_csu_bus_node(struct rockchip_csu *csu) +{ + struct device *dev = csu->dev; + struct device_node *np = dev->of_node; + struct device_node *child; + struct csu_bus *bus; + int bus_cnt = 0, i = 0; + + for_each_available_child_of_node(np, child) + bus_cnt++; + if (bus_cnt <= 0) + return 0; + + csu->bus = devm_kcalloc(dev, bus_cnt, sizeof(*csu->bus), GFP_KERNEL); + if (!csu->bus) + return -ENOMEM; + csu->bus_cnt = bus_cnt; + + for_each_available_child_of_node(np, child) { + bus = &csu->bus[i++]; + if (of_property_read_u32_index(child, "bus-id", 0, &bus->id)) { + dev_info(dev, "get bus-id error\n"); + continue; + } + + if (of_property_read_u32_index(child, "cfg-val", 0, + &bus->cfg_val)) { + dev_info(dev, "get cfg-val error\n"); + continue; + } + if (!bus->cfg_val) { + dev_info(dev, "cfg-val invalid\n"); + continue; + } + + if (of_property_read_u32_index(child, "enable-msk", 0, + &bus->en_mask)) { + dev_info(dev, "get enable_msk error\n"); + continue; + } + + if (rockchip_csu_sip_config(dev, bus->id, bus->cfg_val, bus->en_mask)) + dev_info(dev, "csu smc config error\n"); + } + + return 0; +} + +static const struct of_device_id rockchip_csu_of_match[] = { + { .compatible = "rockchip,rk3562-csu", }, + { }, +}; + +MODULE_DEVICE_TABLE(of, rockchip_csu_of_match); + +static int rockchip_csu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct rockchip_csu *csu; + int ret = 0; + + csu = devm_kzalloc(dev, sizeof(*csu), GFP_KERNEL); + if (!csu) + return -ENOMEM; + + csu->dev = dev; + platform_set_drvdata(pdev, csu); + + rockchip_csu_parse_clk(csu); + + if (of_find_property(np, "rockchip,bus", NULL)) + ret = rockchip_csu_bus_table(csu); + else + ret = rockchip_csu_bus_node(csu); + if (!ret) + rk_csu = csu; + + return ret; +} + +static struct platform_driver rockchip_csu_driver = { + .probe = rockchip_csu_probe, + .driver = { + .name = "rockchip,csu", + .of_match_table = rockchip_csu_of_match, + }, +}; + +static int __init rockchip_csu_init(void) +{ + int ret; + + ret = platform_driver_register(&rockchip_csu_driver); + if (ret) { + pr_err("failed to register csu driver\n"); + return ret; + } + + return 0; +} + +static void __exit rockchip_csu_exit(void) +{ + return platform_driver_unregister(&rockchip_csu_driver); +} + +subsys_initcall(rockchip_csu_init); +module_exit(rockchip_csu_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Finley Xiao "); +MODULE_DESCRIPTION("Rockchip clock subunit driver"); diff --git a/include/dt-bindings/soc/rockchip-csu.h b/include/dt-bindings/soc/rockchip-csu.h new file mode 100644 index 000000000000..8b0442533c3f --- /dev/null +++ b/include/dt-bindings/soc/rockchip-csu.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2023 Rockchip Electronics Co. Ltd. + * Author: Finley Xiao + */ + +#ifndef _DT_BINDINGS_ROCKCHIP_CSU_H +#define _DT_BINDINGS_ROCKCHIP_CSU_H + +#define CSU_GMAC_ACLK 0 +#define CSU_GMAC_PCLK 1 +#define CSU_VOP_ACLK 2 +#define CSU_MCU_CLK 3 + +#endif diff --git a/include/soc/rockchip/rockchip_csu.h b/include/soc/rockchip/rockchip_csu.h new file mode 100644 index 000000000000..4338d68359f7 --- /dev/null +++ b/include/soc/rockchip/rockchip_csu.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2023, Rockchip Electronics Co., Ltd + */ + +#ifndef __SOC_ROCKCHIP_CSU_H +#define __SOC_ROCKCHIP_CSU_H + +#include + +#define CSU_MAX_DIV 8 +#define CSU_DIV_MASK 0x7 +#define CSU_EN_MASK 0xefff + +struct csu_clk; + +#if IS_REACHABLE(CONFIG_ROCKCHIP_CSU) +struct csu_clk *rockchip_csu_get(struct device *dev, const char *name); +int rockchip_csu_enable(struct csu_clk *clk); +int rockchip_csu_disable(struct csu_clk *clk); +int rockchip_csu_set_div(struct csu_clk *clk, unsigned int div); +#else +static inline struct csu_clk * +rockchip_csu_get(struct device *dev, const char *name) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline int rockchip_csu_enable(struct csu_clk *clk) +{ + return -EOPNOTSUPP; +} + +static inline int rockchip_csu_disable(struct csu_clk *clk) +{ + return -EOPNOTSUPP; +} + +static inline int +rockchip_csu_set_div(struct csu_clk *clk, unsigned int div) +{ + return -EOPNOTSUPP; +} +#endif + +#endif From 14640886d0d3cf3b7ced4e70bb0059579b9df6da Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 20 Oct 2023 09:29:29 +0800 Subject: [PATCH 11/20] arm64: configs: rockchip_defconfig: Enable CONFIG_ROCKCHIP_CSU Signed-off-by: Finley Xiao Change-Id: Id6cefadc0c0056be8df84a11f601761f844d1779 --- arch/arm64/configs/rockchip_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rockchip_defconfig b/arch/arm64/configs/rockchip_defconfig index 3bf12675bb19..490ce5736a68 100644 --- a/arch/arm64/configs/rockchip_defconfig +++ b/arch/arm64/configs/rockchip_defconfig @@ -900,6 +900,7 @@ CONFIG_CPU_RK3562=y CONFIG_CPU_RK3568=y CONFIG_CPU_RK3588=y CONFIG_ROCKCHIP_CPUINFO=y +CONFIG_ROCKCHIP_CSU=y CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_IPA=y From 62580d5332817d5a0c531728e062f9642ed90040 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Wed, 22 Nov 2023 11:26:45 +0800 Subject: [PATCH 12/20] arm64: configs: rockchip_linux_defconfig: Enable CONFIG_ROCKCHIP_CSU Signed-off-by: Finley Xiao Change-Id: I38ba978f27b9b9bbdfb1e4d9702d15bac818c101 --- arch/arm64/configs/rockchip_linux_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/rockchip_linux_defconfig b/arch/arm64/configs/rockchip_linux_defconfig index 24abb03c96af..688203de6bae 100644 --- a/arch/arm64/configs/rockchip_linux_defconfig +++ b/arch/arm64/configs/rockchip_linux_defconfig @@ -525,6 +525,7 @@ CONFIG_CPU_RK3568=y CONFIG_CPU_RK3588=y CONFIG_ROCKCHIP_AMP=y CONFIG_ROCKCHIP_CPUINFO=y +CONFIG_ROCKCHIP_CSU=y CONFIG_ROCKCHIP_GRF=y CONFIG_ROCKCHIP_IODOMAIN=y CONFIG_ROCKCHIP_IPA=y From 56960b6e474356e8df0d0edd37ac6dfbc4ffaf9c Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Thu, 19 Oct 2023 21:25:28 +0800 Subject: [PATCH 13/20] Revert "arm64: dts: rockchip: rk3562-evb1-lp4x-v10: Change clkin div to 5 for aclk vo" This reverts commit 24ea6649adbb2c8e66b481cab90a2e9e9fcffa21. Signed-off-by: Finley Xiao Change-Id: Iaa4453872c3addce15c5f78643293dd59a49089c --- .../boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi b/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi index 44f2ff713dde..7fdb0557edda 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562-evb1-lp4x-v10.dtsi @@ -179,18 +179,6 @@ }; }; -&bus_soc { - rockchip,soc-bus-table = <0 0x00a000a8 0x7001>, - <1 0x00a000a8 0x7c39>, - <2 0x00a000a8 0x7c39>, - <3 0x00a000a8 0x7c39>, - <4 0x00a000a5 0xb007>, - <5 0x00a000a8 0x7034>, - <6 0x00a000a8 0x7034>, - <7 0x00a000a8 0x7034>, - <8 0x00a000a8 0x7001>; -}; - &gmac0 { /* Use rgmii-rxid mode to disable rx delay inside Soc */ phy-mode = "rgmii-rxid"; From 5aea0b9686c8277cb90a49a9ad4de60e84cab631 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Thu, 19 Oct 2023 21:25:40 +0800 Subject: [PATCH 14/20] Revert "arm64: dts: rockchip: rk3562-rk817-tablet-v10: Change clkin div to 5 for aclk vo" This reverts commit 26d58236a5e4ee47eb13c2dbbac4b0699a313e18. Signed-off-by: Finley Xiao Change-Id: I24e24d5e806be7202c6002d6f323a89bc9cf967d --- .../boot/dts/rockchip/rk3562-rk817-tablet-v10.dts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts b/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts index 281b65104b53..4f9edc072df7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-v10.dts @@ -209,18 +209,6 @@ cpu-supply = <&vdd_cpu>; }; -&bus_soc { - rockchip,soc-bus-table = <0 0x00a000a8 0x7001>, - <1 0x00a000a8 0x7c39>, - <2 0x00a000a8 0x7c39>, - <3 0x00a000a8 0x7c39>, - <4 0x00a000a5 0xb007>, - <5 0x00a000a8 0x7034>, - <6 0x00a000a8 0x7034>, - <7 0x00a000a8 0x7034>, - <8 0x00a000a8 0x7001>; -}; - &dfi { status = "okay"; }; From 2cb3623b0e2965386895c8e6ffccf5c0ee6b0b7e Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 20 Oct 2023 10:12:55 +0800 Subject: [PATCH 15/20] arm64: dts: rockchip: rk3562: Add csu device node Signed-off-by: Finley Xiao Change-Id: I552b695dff29072d5468b0a081cdc38c8575ebdf --- arch/arm64/boot/dts/rockchip/rk3562.dtsi | 32 +++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/arch/arm64/boot/dts/rockchip/rk3562.dtsi index deefbba2a5eb..7bc9bec10b2c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562.dtsi @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -361,20 +362,6 @@ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; - bus_soc: bus-soc { - compatible = "rockchip,rk3562-bus"; - rockchip,busfreq-policy = "smc"; - rockchip,soc-bus-table = <0 0x00a000a8 0x7001>, - <1 0x00a000a8 0x7c39>, - <2 0x00a000a8 0x7c39>, - <3 0x00a000a8 0x7c39>, - <4 0x00a000a4 0xb007>, - <5 0x00a000a8 0x7034>, - <6 0x00a000a8 0x7034>, - <7 0x00a000a8 0x7034>, - <8 0x00a000a8 0x7001>; - }; - cpuinfo { compatible = "rockchip,cpuinfo"; nvmem-cells = <&otp_id>, <&otp_cpu_version>, <&cpu_code>; @@ -423,6 +410,23 @@ status = "disabled"; }; + csu: csu { + compatible = "rockchip,rk3562-csu"; + rockchip,clock = , + , + , + ; + rockchip,bus = <0 0x00a000a8 0x7001>, + <1 0x00a000a8 0x7c39>, + <2 0x00a000a8 0x7c39>, + <3 0x00a000a8 0x7c39>, + <4 0x00a000a4 0xb007>, + <5 0x00a000a8 0x7034>, + <6 0x00a000a8 0x7034>, + <7 0x00a000a8 0x7034>, + <8 0x00a000a8 0x7001>; + }; + display_subsystem: display-subsystem { compatible = "rockchip,display-subsystem"; ports = <&vop_out>; From a7a8b96367fd6d7e3d7d21eaccdb8fa94e4b39a0 Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 20 Oct 2023 15:36:11 +0800 Subject: [PATCH 16/20] ethernet: stmmac: dwmac-rk: Add csu clock support Signed-off-by: Finley Xiao Change-Id: I2498d053faf8c51f7c39ffd22e5f2bf6871d6a47 --- .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index d445a25cdbfa..687c79455048 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "stmmac_platform.h" #include "dwmac-rk-tool.h" @@ -80,6 +81,9 @@ struct rk_priv_data { unsigned char otp_data; unsigned int bgs_increment; + + struct csu_clk *csu_aclk; + struct csu_clk *csu_pclk; }; /* XPCS */ @@ -2322,6 +2326,21 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) return 0; } +static int rk_gmac_csu_init(struct plat_stmmacenet_data *plat) +{ + struct rk_priv_data *bsp_priv = plat->bsp_priv; + struct device *dev = &bsp_priv->pdev->dev; + + bsp_priv->csu_aclk = rockchip_csu_get(dev, "aclk"); + if (IS_ERR(bsp_priv->csu_aclk)) + bsp_priv->csu_aclk = NULL; + bsp_priv->csu_pclk = rockchip_csu_get(dev, "pclk"); + if (IS_ERR(bsp_priv->csu_pclk)) + bsp_priv->csu_pclk = NULL; + + return 0; +} + static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) { int phy_iface = bsp_priv->phy_iface; @@ -2367,6 +2386,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) bsp_priv->ops->set_clock_selection(bsp_priv, bsp_priv->clock_input, true); + rockchip_csu_disable(bsp_priv->csu_aclk); + rockchip_csu_disable(bsp_priv->csu_pclk); + /** * if (!IS_ERR(bsp_priv->clk_mac)) * clk_prepare_enable(bsp_priv->clk_mac); @@ -2402,6 +2424,9 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) clk_disable_unprepare(bsp_priv->clk_xpcs_eee); + rockchip_csu_enable(bsp_priv->csu_aclk); + rockchip_csu_enable(bsp_priv->csu_pclk); + /** * if (!IS_ERR(bsp_priv->clk_mac)) * clk_disable_unprepare(bsp_priv->clk_mac); @@ -2781,6 +2806,8 @@ static int rk_gmac_probe(struct platform_device *pdev) goto err_remove_config_dt; } + rk_gmac_csu_init(plat_dat); + ret = rk_gmac_clk_init(plat_dat); if (ret) goto err_remove_config_dt; From 29af394d95cc676d4f6b2d4f68864ebf18dc701f Mon Sep 17 00:00:00 2001 From: Finley Xiao Date: Fri, 20 Oct 2023 20:18:16 +0800 Subject: [PATCH 17/20] arm64: dts: rockchip: rk3562: Add rockchip,csu for gmac Signed-off-by: Finley Xiao Change-Id: Iae2cdaa474deaa0f7791f3227b60c4da3ffe4acb --- arch/arm64/boot/dts/rockchip/rk3562.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/arch/arm64/boot/dts/rockchip/rk3562.dtsi index 7bc9bec10b2c..926e5a98de01 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562.dtsi @@ -2841,6 +2841,8 @@ "pclk_mac", "aclk_mac"; resets = <&cru SRST_A_GMAC>; reset-names = "stmmaceth"; + rockchip,csu = <&csu CSU_GMAC_ACLK>, <&csu CSU_GMAC_PCLK>; + rockchip,csu-names = "aclk", "pclk"; snps,mixed-burst; snps,tso; @@ -2959,6 +2961,8 @@ "pclk_mac", "aclk_mac"; resets = <&cru SRST_A_MAC100>; reset-names = "stmmaceth"; + rockchip,csu = <&csu CSU_GMAC_ACLK>, <&csu CSU_GMAC_PCLK>; + rockchip,csu-names = "aclk", "pclk"; status = "disabled"; mdio1: mdio { From 0c94344f327c081305fb9fa62718f9f626eb93a8 Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 17 Nov 2023 18:50:41 +0800 Subject: [PATCH 18/20] drm/rockchip: vop2: Add csu clock support for rk3562 Signed-off-by: Sandy Huang Change-Id: I2f9f962902df0648e3f30ecd26eeb3e8fa475179 --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 9bbe98c2347e..362d0f4d590c 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -884,6 +885,7 @@ struct vop2 { struct clk *pclk; struct reset_control *ahb_rst; struct reset_control *axi_rst; + struct csu_clk *csu_aclk; /* list_head of extend clk */ struct list_head extend_clk_list_head; @@ -6107,6 +6109,27 @@ static int vop2_crtc_get_inital_acm_info(struct drm_crtc *crtc) return 0; } +static void vop2_crtc_csu_set_rate(struct drm_crtc *crtc) +{ + struct vop2_video_port *vp = to_vop2_video_port(crtc); + struct vop2 *vop2 = vp->vop2; + unsigned long aclk_rate = 0, dclk_rate = 0; + u32 csu_div = 0; + + if (!vop2->csu_aclk) + return; + + aclk_rate = clk_get_rate(vop2->aclk); + dclk_rate = clk_get_rate(vp->dclk); + if (!dclk_rate) + return; + + /* aclk >= 1/2 * dclk */ + csu_div = aclk_rate * 2 / dclk_rate; + + rockchip_csu_set_div(vop2->csu_aclk, csu_div); +} + static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data) { struct vop2_video_port *vp = to_vop2_video_port(crtc); @@ -6186,6 +6209,8 @@ static int vop2_crtc_loader_protect(struct drm_crtc *crtc, bool on, void *data) cubic_lut_mst = cubic_lut->offset + private->cubic_lut_dma_addr; VOP_MODULE_SET(vop2, vp, cubic_lut_mst, cubic_lut_mst); } + + vop2_crtc_csu_set_rate(crtc); } else { vop2_crtc_atomic_disable(crtc, NULL); } @@ -8120,6 +8145,7 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state if (is_vop3(vop2)) vop3_setup_pipe_dly(vp, NULL); + vop2_crtc_csu_set_rate(crtc); vop2_cfg_done(crtc); /* @@ -11969,6 +11995,10 @@ static int vop2_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(vop2->axi_rst); } + vop2->csu_aclk = rockchip_csu_get(dev, "aclk"); + if (IS_ERR(vop2->csu_aclk)) + vop2->csu_aclk = NULL; + vop2->irq = platform_get_irq(pdev, 0); if (vop2->irq < 0) { DRM_DEV_ERROR(dev, "cannot find irq for vop2\n"); From 7acc7fe0adcc8f6c7fcb838f80d43bed75c1f22e Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 17 Nov 2023 18:50:04 +0800 Subject: [PATCH 19/20] arm64: dts: rockchip: rk3562: Add csu-clocks for vop Signed-off-by: Sandy Huang Change-Id: I6c3993720446fb95683ae10f9b3e1b2aeac96959 --- arch/arm64/boot/dts/rockchip/rk3562.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/arch/arm64/boot/dts/rockchip/rk3562.dtsi index 926e5a98de01..7c15aba1fd87 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562.dtsi @@ -1900,6 +1900,8 @@ reset-names = "axi", "ahb", "dclk_vp0"; + rockchip,csu = <&csu CSU_VOP_ACLK>; + rockchip,csu-names = "aclk"; iommus = <&vop_mmu>; power-domains = <&power RK3562_PD_VO>; rockchip,grf = <&ioc_grf>; From bc95e6862a3f13d4ae07e5a5265f142641bdef02 Mon Sep 17 00:00:00 2001 From: Zefa Chen Date: Fri, 24 Nov 2023 17:34:02 +0800 Subject: [PATCH 20/20] media: i2c: mis4001 driver update version 0.01.02 1. update gain control with 0x401d 2. update time control with 0x4007 3. update vts with stream off/on Signed-off-by: Zefa Chen Change-Id: I35f821a944bebd4db8ec2e2cf3a16e2313eeb1b0 --- drivers/media/i2c/mis4001.c | 578 ++++++++++++++++++------------------ 1 file changed, 292 insertions(+), 286 deletions(-) diff --git a/drivers/media/i2c/mis4001.c b/drivers/media/i2c/mis4001.c index d73e92dd768c..a23f73aec373 100644 --- a/drivers/media/i2c/mis4001.c +++ b/drivers/media/i2c/mis4001.c @@ -27,7 +27,7 @@ #include #include -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01) +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -165,177 +165,177 @@ static const struct regval mis4001_global_regs[] = { * mipi_datarate per lane 337.5Mbps, 2lane */ static const struct regval mis4001_linear_10_2560x1440_regs[] = { - {0x300a, 0x01}, - {0x3006, 0x02}, - {0x4220, 0x2b}, - {0x4221, 0x6b}, - {0x4222, 0xab}, - {0x4223, 0xeb}, - {0x3011, 0x2b}, - {0x3302, 0x02}, - {0x3307, 0x64}, - {0x3306, 0x01}, - {0x3309, 0x01}, - {0x3308, 0x03}, - {0x330a, 0x04}, - {0x330b, 0x09}, - {0x310f, 0x68}, - {0x310e, 0x0d}, - {0x310d, 0x25}, - {0x310c, 0x06}, - {0x3115, 0x10}, - {0x3114, 0x00}, - {0x3117, 0x0f}, - {0x3116, 0x0a}, - {0x3111, 0xfc}, - {0x3110, 0x00}, - {0x3113, 0x9d}, - {0x3112, 0x06}, - {0x3128, 0x0f},//FW<4096 FFF - {0x3129, 0xff}, - {0x3012, 0x03}, - {0x3f00, 0x01}, - {0x3f02, 0x07}, - {0x3f01, 0x00}, - {0x3f04, 0x2a}, - {0x3f03, 0x00}, - {0x3f06, 0xa5}, - {0x3f05, 0x04}, - {0x3f08, 0xff}, - {0x3f07, 0x1f}, - {0x3f0a, 0xa4}, - {0x3f09, 0x01}, - {0x3f0c, 0x38}, - {0x3f0b, 0x00}, - {0x3f0e, 0xff}, - {0x3f0d, 0x1f}, - {0x3f10, 0xff}, - {0x3f0f, 0x1f}, - {0x3f13, 0x07}, - {0x3f12, 0x00}, - {0x3f15, 0x9d}, - {0x3f14, 0x01}, - {0x3f17, 0x31}, - {0x3f16, 0x00}, - {0x3f19, 0x73}, - {0x3f18, 0x01}, - {0x3f1b, 0x00}, - {0x3f1a, 0x00}, - {0x3f1d, 0xa9}, - {0x3f1c, 0x04}, - {0x3f1f, 0xff}, - {0x3f1e, 0x1f}, - {0x3f21, 0xff}, - {0x3f20, 0x1f}, - {0x3f23, 0x85}, - {0x3f22, 0x00}, - {0x3f25, 0x27}, - {0x3f24, 0x01}, - {0x3f28, 0x46}, - {0x3f27, 0x00}, - {0x3f2a, 0x07}, - {0x3f29, 0x00}, - {0x3f2c, 0x3f}, - {0x3f2b, 0x00}, - {0x3f2e, 0x70}, - {0x3f2d, 0x01}, - {0x3f30, 0x38}, - {0x3f2f, 0x00}, - {0x3f32, 0x3f}, - {0x3f31, 0x00}, - {0x3f34, 0xd1}, - {0x3f33, 0x00}, - {0x3f36, 0xc0}, - {0x3f35, 0x00}, - {0x3f38, 0x2f}, - {0x3f37, 0x02}, - {0x3f3a, 0x5d}, - {0x3f39, 0x02}, - {0x3f4f, 0x5d}, - {0x3f4e, 0x02}, - {0x3f51, 0x5d}, - {0x3f50, 0x02}, - {0x3f53, 0x5d}, - {0x3f52, 0x02}, - {0x3f55, 0x5d}, - {0x3f54, 0x02}, - {0x3f3c, 0x9a}, - {0x3f3b, 0x00}, - {0x3f3e, 0x09}, - {0x3f3d, 0x04}, - {0x3f40, 0x93}, - {0x3f3f, 0x01}, - {0x3f42, 0x8f}, - {0x3f41, 0x00}, - {0x3f44, 0xb0}, - {0x3f43, 0x04}, - {0x3129, 0x45}, - {0x3128, 0x00}, - {0x312b, 0x4a}, - {0x312a, 0x00}, - {0x312f, 0xb2}, - {0x312e, 0x00}, - {0x3124, 0x09}, - {0x4200, 0x09}, - {0x4201, 0x00}, - {0x4214, 0x60}, - {0x420E, 0x94}, - {0x4240, 0x8d}, - {0x4242, 0x03}, - {0x4224, 0x00}, - {0x4225, 0x0a}, - {0x4226, 0xa0}, - {0x4227, 0x05}, - {0x4228, 0x00}, - {0x4229, 0x0a}, - {0x422a, 0xa0}, - {0x422b, 0x05}, - {0x422c, 0x00}, - {0x422d, 0x0a}, - {0x422e, 0xa0}, - {0x422f, 0x05}, - {0x4230, 0x00}, - {0x4231, 0x0a}, - {0x4232, 0xa0}, - {0x4233, 0x05}, - {0x4509, 0x0f}, - {0x4505, 0x00}, - {0x4501, 0xff}, - {0x4502, 0x33}, - {0x4503, 0x11}, - {0x4501, 0xf0}, - {0x4502, 0x30}, - {0x4503, 0x10}, - {0x3A01, 0xA0}, - {0x401E, 0x3C}, - {0x401d, 0xa0}, - {0x3012, 0x03}, - {0x3E00, 0x00}, - {0x3E01, 0x10}, - {0x400D, 0x30}, - {0x3500, 0x1b}, //1b/13 - {0x3501, 0x03}, - {0x3508, 0x0a}, - {0x3508, 0x04}, - {0x3513, 0x01}, - {0x3514, 0x09}, - {0x3515, 0x0b}, - {0x3702, 0x80}, - {0x3704, 0x80}, - {0x3706, 0x80}, - {0x3708, 0x80}, - {0x400D, 0x30}, //优化奇偶行及行噪 - {0x4004, 0x20}, //RCS CM电流最小优化横带 - {0x4005, 0x0c}, - {0x4009, 0x09}, - {0x400a, 0x48}, - {0x4006, 0x86}, - {0x4019, 0x08}, - {0x4003, 0x0a}, - {0x3f42, 0x58}, - {0x3f49, 0x60}, - {0x3f38, 0x4d}, - {REG_NULL, 0x00}, + {0x300a, 0x01}, + {0x3006, 0x02}, + {0x4220, 0x2b}, + {0x4221, 0x6b}, + {0x4222, 0xab}, + {0x4223, 0xeb}, + {0x3011, 0x2b}, + {0x3302, 0x02}, + {0x3307, 0x64}, + {0x3306, 0x01}, + {0x3309, 0x01}, + {0x3308, 0x03}, + {0x330a, 0x04}, + {0x330b, 0x09}, + {0x310f, 0x68}, + {0x310e, 0x0d}, + {0x310d, 0x25}, + {0x310c, 0x06}, + {0x3115, 0x10}, + {0x3114, 0x00}, + {0x3117, 0x0f}, + {0x3116, 0x0a}, + {0x3111, 0xfc}, + {0x3110, 0x00}, + {0x3113, 0x9d}, + {0x3112, 0x06}, + {0x3128, 0x0f},//FW<4096 FFF + {0x3129, 0xff}, + {0x3012, 0x03}, + {0x3f00, 0x01}, + {0x3f02, 0x07}, + {0x3f01, 0x00}, + {0x3f04, 0x2a}, + {0x3f03, 0x00}, + {0x3f06, 0xa5}, + {0x3f05, 0x04}, + {0x3f08, 0xff}, + {0x3f07, 0x1f}, + {0x3f0a, 0xa4}, + {0x3f09, 0x01}, + {0x3f0c, 0x38}, + {0x3f0b, 0x00}, + {0x3f0e, 0xff}, + {0x3f0d, 0x1f}, + {0x3f10, 0xff}, + {0x3f0f, 0x1f}, + {0x3f13, 0x07}, + {0x3f12, 0x00}, + {0x3f15, 0x9d}, + {0x3f14, 0x01}, + {0x3f17, 0x31}, + {0x3f16, 0x00}, + {0x3f19, 0x73}, + {0x3f18, 0x01}, + {0x3f1b, 0x00}, + {0x3f1a, 0x00}, + {0x3f1d, 0xa9}, + {0x3f1c, 0x04}, + {0x3f1f, 0xff}, + {0x3f1e, 0x1f}, + {0x3f21, 0xff}, + {0x3f20, 0x1f}, + {0x3f23, 0x85}, + {0x3f22, 0x00}, + {0x3f25, 0x27}, + {0x3f24, 0x01}, + {0x3f28, 0x46}, + {0x3f27, 0x00}, + {0x3f2a, 0x07}, + {0x3f29, 0x00}, + {0x3f2c, 0x3f}, + {0x3f2b, 0x00}, + {0x3f2e, 0x70}, + {0x3f2d, 0x01}, + {0x3f30, 0x38}, + {0x3f2f, 0x00}, + {0x3f32, 0x3f}, + {0x3f31, 0x00}, + {0x3f34, 0xd1}, + {0x3f33, 0x00}, + {0x3f36, 0xc0}, + {0x3f35, 0x00}, + {0x3f38, 0x2f}, + {0x3f37, 0x02}, + {0x3f3a, 0x5d}, + {0x3f39, 0x02}, + {0x3f4f, 0x5d}, + {0x3f4e, 0x02}, + {0x3f51, 0x5d}, + {0x3f50, 0x02}, + {0x3f53, 0x5d}, + {0x3f52, 0x02}, + {0x3f55, 0x5d}, + {0x3f54, 0x02}, + {0x3f3c, 0x9a}, + {0x3f3b, 0x00}, + {0x3f3e, 0x09}, + {0x3f3d, 0x04}, + {0x3f40, 0x93}, + {0x3f3f, 0x01}, + {0x3f42, 0x8f}, + {0x3f41, 0x00}, + {0x3f44, 0xb0}, + {0x3f43, 0x04}, + {0x3129, 0x45}, + {0x3128, 0x00}, + {0x312b, 0x4a}, + {0x312a, 0x00}, + {0x312f, 0xb2}, + {0x312e, 0x00}, + {0x3124, 0x09}, + {0x4200, 0x09}, + {0x4201, 0x00}, + {0x4214, 0x60}, + {0x420E, 0x94}, + {0x4240, 0x8d}, + {0x4242, 0x03}, + {0x4224, 0x00}, + {0x4225, 0x0a}, + {0x4226, 0xa0}, + {0x4227, 0x05}, + {0x4228, 0x00}, + {0x4229, 0x0a}, + {0x422a, 0xa0}, + {0x422b, 0x05}, + {0x422c, 0x00}, + {0x422d, 0x0a}, + {0x422e, 0xa0}, + {0x422f, 0x05}, + {0x4230, 0x00}, + {0x4231, 0x0a}, + {0x4232, 0xa0}, + {0x4233, 0x05}, + {0x4509, 0x0f}, + {0x4505, 0x00}, + {0x4501, 0xff}, + {0x4502, 0x33}, + {0x4503, 0x11}, + {0x4501, 0xf0}, + {0x4502, 0x30}, + {0x4503, 0x10}, + {0x3A01, 0xA0}, + {0x401E, 0x3C}, + {0x401d, 0xa0}, + {0x3012, 0x03}, + {0x3E00, 0x00}, + {0x3E01, 0x10}, + {0x400D, 0x30}, + {0x3500, 0x1b}, //1b/13 + {0x3501, 0x03}, + {0x3508, 0x0a}, + {0x3508, 0x04}, + {0x3513, 0x01}, + {0x3514, 0x09}, + {0x3515, 0x0b}, + {0x3702, 0x80}, + {0x3704, 0x80}, + {0x3706, 0x80}, + {0x3708, 0x80}, + {0x400D, 0x30}, //优化奇偶行及行噪 + {0x4004, 0x20}, //RCS CM电流最小优化横带 + {0x4005, 0x0c}, + {0x4009, 0x09}, + {0x400a, 0x48}, + {0x4006, 0x86}, + {0x4019, 0x08}, + {0x4003, 0x0a}, + {0x3f42, 0x58}, + {0x3f49, 0x60}, + {0x3f38, 0x4d}, + {REG_NULL, 0x00}, }; static const struct mis4001_mode supported_modes[] = { @@ -483,6 +483,7 @@ static int mis4001_set_gain_reg(struct mis4001 *mis4001, u32 gain) { u8 gain_h, gain_l, u8Reg0x3102, u8Reg0x3a00, u8Reg0x3a01, u8Reg0x4003; int ret = 0; + u8 u8Reg0x401d = 0; if (gain < 128) gain = 128; @@ -490,89 +491,97 @@ static int mis4001_set_gain_reg(struct mis4001 *mis4001, u32 gain) gain = MIS4001_GAIN_MAX; if (128 <= gain && gain < 256) {//128 * 2 - gain_h = 0; - gain_l = (gain-128)/4 ; - u8Reg0x3a00 = 0; - u8Reg0x3a01 = 160; //128->160, 高亮偏粉 - } else if (gain >= 256 && gain < 512) {//128 * 4 - gain_h = 1; - gain_l = (gain-256)/8; - u8Reg0x3a00 = 0; - u8Reg0x3a01 = 160; - } else if (gain >= 512 && gain < 1024) {//128 * 8 - gain_h = 2; - gain_l = (gain-512)/16; - u8Reg0x3a00 = 0; - u8Reg0x3a01 = 160; - } else if (gain >= 1024 && gain < 2048) {//128 * 16 - gain_h = 3; - gain_l = (gain-1024)/32; - u8Reg0x3a00 = 0; - u8Reg0x3a01 = 160; - } else if (2048 <= gain && gain < 4096) {//128 * 32 Dgain - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 0; - u8Reg0x3a01 = ((gain-2048)/16 + 128); - u8Reg0x3a01 = (u8Reg0x3a01<160)?160:u8Reg0x3a01; - } else if (gain >= 4096 && gain < 8192) {//128 * 64 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 1; - u8Reg0x3a01 =((gain-4096)/16); - } else if (gain >= 8192 && gain < 12288) {//128 * 96 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 2; - u8Reg0x3a01 = ((gain-8192)/16); - } else if (gain >= 12288 && gain < 16384) {//128 * 128 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 3; - u8Reg0x3a01 = ((gain-12288)/16); - } else if (gain >= 16384 && gain < 20480) {//128 * 160 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 4; - u8Reg0x3a01 = ((gain-16384)/16); - } else if (gain >= 20480 && gain < 24576) {//128 * 192 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 5; - u8Reg0x3a01 = ((gain-20480)/16); - } else if (gain >= 24576 && gain < 28672) {//128 * 224 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 6; - u8Reg0x3a01 = ((gain-24576)/16); - } else if (gain >= 28672 && gain < 32768) {//128 * 256 - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 7; - u8Reg0x3a01 = ((gain-28672)/16); - } else { - gain_h = 3; - gain_l = 31; - u8Reg0x3a00 = 7; - u8Reg0x3a01 = 255; - } + gain_h = 0; + gain_l = (gain - 128) / 4; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; //128->160, 高亮偏粉 + } else if (gain >= 256 && gain < 512) {//128 * 4 + gain_h = 1; + gain_l = (gain - 256) / 8; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 512 && gain < 1024) {//128 * 8 + gain_h = 2; + gain_l = (gain - 512) / 16; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 1024 && gain < 2048) {//128 * 16 + gain_h = 3; + gain_l = (gain - 1024) / 32; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = 160; + } else if (gain >= 2048 && gain < 4096) {//128 * 32 Dgain + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 0; + u8Reg0x3a01 = ((gain - 2048) / 16 + 128); + u8Reg0x3a01 = (u8Reg0x3a01 < 160) ? 160 : u8Reg0x3a01; + } else if (gain >= 4096 && gain < 8192) {//128 * 64 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 1; + u8Reg0x3a01 = ((gain - 4096) / 16); + } else if (gain >= 8192 && gain < 12288) {//128 * 96 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 2; + u8Reg0x3a01 = ((gain - 8192) / 16); + } else if (gain >= 12288 && gain < 16384) {//128 * 128 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 3; + u8Reg0x3a01 = ((gain - 12288) / 16); + } else if (gain >= 16384 && gain < 20480) {//128 * 160 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 4; + u8Reg0x3a01 = ((gain - 16384) / 16); + } else if (gain >= 20480 && gain < 24576) {//128 * 192 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 5; + u8Reg0x3a01 = ((gain - 20480) / 16); + } else if (gain >= 24576 && gain < 28672) {//128 * 224 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 6; + u8Reg0x3a01 = ((gain - 24576) / 16); + } else if (gain >= 28672 && gain < 32768) {//128 * 256 + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 7; + u8Reg0x3a01 = ((gain - 28672) / 16); + } else { + gain_h = 3; + gain_l = 31; + u8Reg0x3a00 = 7; + u8Reg0x3a01 = 255; + } - u8Reg0x3102 = ((gain_h << 5)|gain_l); + u8Reg0x3102 = ((gain_h << 5) | gain_l); // 竖条纹优化,但低增益下需添加防止太阳黑子逻辑 - if (128 <= gain && gain <= 256) + if (gain >= 128 && gain <= 256) { u8Reg0x4003 = 0xb; - else + u8Reg0x401d = 0xa0; + } else { u8Reg0x4003 = 0xa; + u8Reg0x401d = 0xa7; + } ret = mis4001_write_reg(mis4001->client, - 0x4003, + 0x401d, MIS4001_REG_VALUE_08BIT, - u8Reg0x4003); + u8Reg0x401d); + ret |= mis4001_write_reg(mis4001->client, - MIS4001_REG_DIG_GAIN, - MIS4001_REG_VALUE_08BIT, - u8Reg0x3a00); + 0x4003, + MIS4001_REG_VALUE_08BIT, + u8Reg0x4003); + ret |= mis4001_write_reg(mis4001->client, + MIS4001_REG_DIG_GAIN, + MIS4001_REG_VALUE_08BIT, + u8Reg0x3a00); ret |= mis4001_write_reg(mis4001->client, MIS4001_REG_DIG_FINE_GAIN, MIS4001_REG_VALUE_08BIT, @@ -1211,10 +1220,8 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl) s64 max; int ret = 0; u32 val = 0; - u32 u32Read0x3102 = 0; - u32 exp_h = 0; - u32 exp_l = 0; - u32 u32Reg0x4007, expmin, expmax, exp_value = 0; + u32 u32Reg0x4007, expmin, expmax; + u64 sleep_time = 0; /* Propagate change of current control to all related controls */ switch (ctrl->id) { @@ -1245,6 +1252,25 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl) MIS4001_REG_EXPOSURE_L, MIS4001_REG_VALUE_08BIT, MIS4001_FETCH_EXP_L(val)); + + /* Special strategy: To solve the problem of exposure layering: + * When the exposure is not fully filled, the gain will be increased, + * resulting in layering phenomenon + */ + + //When the exposure time is 1/200 (0.005) s, the exp register is 196 + expmin = (mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator) + * mis4001->cur_mode->vts_def * 1 / 200; + expmax = mis4001->cur_mode->vts_def - expmin; + if (((expmin <= val) && (expmax >= val))) + u32Reg0x4007 = 0x78; + else + u32Reg0x4007 = 0xc4; + + ret |= mis4001_write_reg(mis4001->client, + 0x4007, + MIS4001_REG_VALUE_08BIT, + u32Reg0x4007); } break; case V4L2_CID_ANALOGUE_GAIN: @@ -1254,17 +1280,29 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: dev_dbg(&client->dev, "set vblank 0x%x\n", ctrl->val); + mis4001->cur_vts = ctrl->val + mis4001->cur_mode->height; ret = mis4001_write_reg(mis4001->client, - MIS4001_REG_VTS_H, + MIS4001_REG_CTRL_MODE, MIS4001_REG_VALUE_08BIT, - (ctrl->val + mis4001->cur_mode->height) - >> 8); + 0x02); + sleep_time = mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator * + mis4001->cur_mode->vts_def / mis4001->cur_vts; + sleep_time = div_u64(1000000, sleep_time); + usleep_range(sleep_time, sleep_time + 1000); + ret |= mis4001_write_reg(mis4001->client, + MIS4001_REG_VTS_H, + MIS4001_REG_VALUE_08BIT, + (ctrl->val + mis4001->cur_mode->height) + >> 8); ret |= mis4001_write_reg(mis4001->client, MIS4001_REG_VTS_L, MIS4001_REG_VALUE_08BIT, (ctrl->val + mis4001->cur_mode->height) & 0xff); - mis4001->cur_vts = ctrl->val + mis4001->cur_mode->height; + ret |= mis4001_write_reg(mis4001->client, + MIS4001_REG_CTRL_MODE, + MIS4001_REG_VALUE_08BIT, + 0x00); if (mis4001->cur_vts != mis4001->cur_mode->vts_def) mis4001_modify_fps_info(mis4001); break; @@ -1294,38 +1332,6 @@ static int mis4001_set_ctrl(struct v4l2_ctrl *ctrl) __func__, ctrl->id, ctrl->val); break; } - ret = mis4001_read_reg(mis4001->client, - MIS4001_REG_ANA_GAIN, - MIS4001_REG_VALUE_08BIT, - &u32Read0x3102); - ret |= mis4001_read_reg(mis4001->client, - MIS4001_REG_EXPOSURE_H, - MIS4001_REG_VALUE_08BIT, - &exp_h); - ret |= mis4001_read_reg(mis4001->client, - MIS4001_REG_EXPOSURE_L, - MIS4001_REG_VALUE_08BIT, - &exp_l); - exp_value = ((exp_h << 8) | exp_l); - - /* Special strategy: To solve the problem of exposure layering: - * When the exposure is not fully filled, the gain will be increased, - * resulting in layering phenomenon */ - - //When the exposure time is 1/200 (0.005) s, the exp register is 196 - expmin = (mis4001->cur_mode->max_fps.denominator / mis4001->cur_mode->max_fps.numerator) - * mis4001->cur_mode->vts_def * 1/200; - expmax = mis4001->cur_mode->vts_def - expmin; - if((127 == u32Read0x3102) && - ((expmin <= exp_value) && (expmax >= exp_value))) - u32Reg0x4007 = 0x78; - else - u32Reg0x4007 = 0xc4; - - ret = mis4001_write_reg(mis4001->client, - 0x4007, - MIS4001_REG_VALUE_08BIT, - u32Reg0x4007); pm_runtime_put(&client->dev);