Merge commit '0b1e03cc77f7677a8f5d837bc150a09c1b46c605'

* commit '0b1e03cc77f7677a8f5d837bc150a09c1b46c605': (99 commits)
  arm64: dts: rockchip: Remove property support-psr of eDP nodes
  drm/rockchip: Move the init/cleanup of self refresh helper from VOP/VOP2 to eDP/RGB drivers
  drm/rockchip: vop: Add errno if &vop->lut memory allocation failed in vop_create_crtc()
  drm/bridge: analogix_dp: Add &analogix_dp_plat_data.disable_psr to check whether to disable PSR
  PCI: rockchip: dw-dmatest: Fix compile warning
  dt-bindings: display: rockchip: analogix-dp: Add property rockchip,disable-psr
  dt-bindings: display: rockchip: analogix-dp: Add properties for dual-channel/split modes
  dt-bindings: display: rockchip: analogix-dp: Add compatible for RK3568
  dt-bindings: display: rockchip: analogix-dp: Add support for RK3576
  UPSTREAM: dt-bindings: display: rockchip: analogix-dp: Add support for RK3588
  UPSTREAM: dt-bindings: display: rockchip: convert analogix_dp-rockchip.txt to yaml
  UPSTREAM: dt-bindings: display: bridge: convert analogix_dp.txt to yaml
  drm/rockchip: dw_hdmi: Do not enable DSC when the DSC compression ratio is below 0.375.
  media: i2c: ov13b10: add ov13b10 sensor driver
  soc: rockchip: opp_select: avoid duplicate of_find_property
  pinctrl: rockchip: Correctly support rk3308/rk3308b/rk3308bs
  video: rockchip: rga3: "reg" debug log add iommu readback register printing
  video: rockchip: rga3: restore iommu status on soft-reset
  video: rockchip: rga3: modify the reset method to replace auto_rst on RK3576
  phy: rockchip: inno-usb2: Destroy chg_worker on probe failure
  ...

Change-Id: Ic14227ff8f6b7eada9a188284e58b326e9a024f6
This commit is contained in:
Tao Huang
2025-07-29 17:45:31 +08:00
137 changed files with 5640 additions and 1870 deletions

View File

@@ -15,6 +15,9 @@ properties:
enum:
- rockchip,rk3288-dp
- rockchip,rk3399-edp
- rockchip,rk3568-edp
- rockchip,rk3576-edp
- rockchip,rk3588-edp
clocks:
minItems: 2
@@ -31,16 +34,66 @@ properties:
maxItems: 1
resets:
maxItems: 1
minItems: 1
maxItems: 2
reset-names:
const: dp
minItems: 1
items:
- const: dp
- const: apb
rockchip,data-swap:
description:
Indicate whether to enable data swap function for split mode or dual
channel mode. It can be helpful to deal with the reversed hardware
design issue in left and right display interfaces.
rockchip,disable-psr:
description:
Indicate whether to disable PSR function when the PSR
capability of Sink device is detected.
rockchip,dual-channel:
description:
Indicate whether to enable dual channel mode, which horizontally
splits a single video port's output to drive one displays with
identical interfaces and consistent display timing.
| | ---> | eDP0 | \ | |
| Video Port | --> | Panel |
| | ---> | eDP1 | / | |
rockchip,dual-connector-split:
description:
Indicate whether to enable dual connector split mode, which horizontally
splits a single video port's output to drive two displays with different
interfaces and consistent display timing.
| | ---> | eDP0 | ---> | | |
| Video Port | | Panel0(Left) | Panel1(right) |
| | ---> | MIPI1 | | | |
----------------------------------^
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
This SoC makes use of GRF regs.
rockchip,left-display:
description:
Assign the specific interface for the left display in dual connector
split mode. It can be helpful to deal with the reversed hardware
design issue in left and right display interfaces.
rockchip,split-mode:
description:
Indicate whether to enable split mode, which horizontally splits
a single video port's output to drive two displays with identical
interfaces and consistent display timing.
| | ---> | eDP0 | ---> | | |
| Video Port | | Panel0(Left) | Panel1(right) |
| | ---> | eDP1 | | | |
---------------------------------^
required:
- compatible
- clocks
@@ -52,6 +105,21 @@ required:
allOf:
- $ref: /schemas/display/bridge/analogix,dp.yaml#
- if:
properties:
compatible:
contains:
enum:
- rockchip,rk3568-edp
- rockchip,rk3576-edp
- rockchip,rk3588-edp
then:
properties:
resets:
minItems: 2
reset-names:
minItems: 2
unevaluatedProperties: false
examples:

View File

@@ -64,11 +64,18 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
rv1126b-evb1-v10-spi-nor.dtb \
rv1126b-evb1-v11.dtb \
rv1126b-evb1-v11-dual-4k.dtb \
rv1126b-evb1-v11-fastboot-emmc.dtb \
rv1126b-evb1-v11-fastboot-spi-nand.dtb \
rv1126b-evb1-v11-fastboot-spi-nor.dtb \
rv1126b-evb1-v11-spi-nor.dtb \
rv1126b-evb2-v10.dtb \
rv1126b-evb2-v10-dv.dtb \
rv1126b-evb2-v10-mcu-k350c4516t.dtb \
rv1126b-evb2-v10-rgb-Q7050ITH2641AA1T.dtb \
rv1126b-evb2-v10-sii9022-bt1120-to-hdmi.dtb \
rv1126b-evb2-v10-tb-400w.dtb \
rv1126b-evb2-v10-tb-400w-emmc.dtb \
rv1126b-evb2-v10-tb-400w-spi-nor.dtb \
rv1126b-evb2-v12-aov-dual-cam.dtb \
rv1126b-evb3-v10.dtb \
rv1126b-evb4-v10.dtb \
rv1126b-iotest-v10.dtb \

View File

@@ -20,8 +20,9 @@
interrupts = <RK_PC2 IRQ_TYPE_LEVEL_LOW>;
pwrctrl-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-names = "default", "pmic-reset";
pinctrl-0 = <&pmic_int>;
pinctrl-1 = <&soc_pwrctrl_reset>;
rockchip,system-power-controller;
wakeup-source;

View File

@@ -632,6 +632,10 @@
pmic_int: pmic-int {
rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
};
soc_pwrctrl_reset: soc-pwrctrl-reset {
rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_output_high>;
};
};
sdcard {

View File

@@ -526,6 +526,10 @@
pmic_int: pmic-int {
rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
};
soc_pwrctrl_reset: soc-pwrctrl-reset {
rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_output_high>;
};
};
psensor {

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v11-fastboot-emmc.dts"
/ {
model = "Rockchip RV1126B EVB1 V11 Fastboot Board";
compatible = "rockchip,rv1126b-evb1-v11-fastboot", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v11-fastboot-spi-nand.dts"
/ {
model = "Rockchip RV1126B EVB1 V11 Board";
compatible = "rockchip,rv1126b-evb1-v11-fastboot-spi-nand", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,23 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v11-fastboot-spi-nor.dts"
/ {
model = "Rockchip RV1126B EVB1 V11 Board";
compatible = "rockchip,rv1126b-evb1-v11-fastboot-spi-nand", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (20 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4a040000 (10 * 0x00100000)>;
};

View File

@@ -0,0 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb1-v11-spi-nor.dts"

View File

@@ -0,0 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb2-v10-dv.dts"

View File

@@ -0,0 +1,81 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include "arm64/rockchip/rv1126b.dtsi"
#include "arm64/rockchip/rv1126b-evb.dtsi"
#include "arm64/rockchip/rv1126b-evb2-v10.dtsi"
#include "rv1126b-thunder-boot-cam.dtsi"
#include "rv1126b-thunder-boot-emmc.dtsi"
/ {
model = "Rockchip RV1126B EVB2 V10 TB 400W eMMC Board";
compatible = "rockchip,rv1126b-evb2-v10-tb-400w-emmc", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_nr_threads=-1 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&emmc {
bus-width = <8>;
cap-mmc-highspeed;
non-removable;
mmc-hs200-1_8v;
rockchip,default-sample-phase = <90>;
no-sdio;
no-sd;
status = "okay";
};
&fspi0 {
status = "disabled";
};
&i2c3 {
clock-frequency = <400000>;
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_pins>;
rockchip,amp-shared;
status = "okay";
sc450ai: sc450ai@30 {
compatible = "smartsens,sc450ai";
reg = <0x30>;
clocks = <&cru CLK_MIPI0_OUT2IO>;
clock-names = "xvclk";
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&cam_clk0_pins>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
port {
cam0_out: endpoint {
remote-endpoint = <&csi_dphy_input0>;
data-lanes = <1 2 3 4>;
};
};
};
};
&ramdisk_r {
reg = <0x48c40000 (60 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4c840000 (30 * 0x00100000)>;
};
&rkisp_thunderboot {
/* reg's offset MUST match with RTOS */
/*
* vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num)
* e.g. 2688x1520: 0x14c8000
*/
reg = <0x41320000 0x14c8000>;
};

View File

@@ -4,15 +4,15 @@
*/
/dts-v1/;
#include "rv1126b.dtsi"
#include "rv1126b-evb.dtsi"
#include "rv1126b-evb2-v10.dtsi"
#include "arm64/rockchip/rv1126b.dtsi"
#include "arm64/rockchip/rv1126b-evb.dtsi"
#include "arm64/rockchip/rv1126b-evb2-v10.dtsi"
#include "rv1126b-thunder-boot-cam.dtsi"
#include "rv1126b-thunder-boot-spi-nor.dtsi"
/ {
model = "Rockchip RV1126B EVB2 V10 ARM64 TB 400W Board";
compatible = "rockchip,rv1126b-evb2-v10-tb-400w", "rockchip,rv1126b";
model = "Rockchip RV1126B EVB2 V10 TB 400W SPI NorFlash Board";
compatible = "rockchip,rv1126b-evb2-v10-tb-400w-spi-nor", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_nr_threads=-1 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
@@ -28,7 +28,6 @@
sc450ai: sc450ai@30 {
compatible = "smartsens,sc450ai";
status = "okay";
reg = <0x30>;
clocks = <&cru CLK_MIPI0_OUT2IO>;
clock-names = "xvclk";
@@ -50,11 +49,11 @@
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
reg = <0x48c40000 (30 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
reg = <0x4aa40000 (20 * 0x00100000)>;
};
&rkisp_thunderboot {
@@ -65,19 +64,3 @@
*/
reg = <0x41320000 0x14c8000>;
};
&usb2phy {
status = "okay";
};
&usb2phy_otg {
status = "okay";
};
&usb3phy {
status = "okay";
};
&usb_drd_dwc3 {
status = "okay";
};

View File

@@ -1,19 +0,0 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb2-v10-tb-400w.dts"
/ {
model = "Rockchip RV1126B EVB2 V10 TB 400W Board";
compatible = "rockchip,rv1126b-evb2-v10-tb-400w", "rockchip,rv1126b";
};
&ramdisk_r {
reg = <0x48c40000 (30 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4aa40000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "arm64/rockchip/rv1126b-evb2-v10-aov-dual-cam.dts"

View File

@@ -116,7 +116,7 @@
};
rtos: rtos@48c00000 {
reg = <0x48c00000 0x0003a000>;
reg = <0x48c00000 0x0003c000>;
};
mcu_log: mcu_log@48c3c000 {

View File

@@ -0,0 +1,31 @@
# CONFIG_ARM_PSCI_CPUIDLE is not set
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CPU_FREQ_TIMES is not set
# CONFIG_CPU_FREQ_THERMAL is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_FTRACE is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_MALI_BIFROST_ENABLE_TRACE is not set
# CONFIG_MALI_BIFROST_SYSTEM_TRACE is not set
# CONFIG_PSI is not set
# CONFIG_PERF_EVENTS is not set
# CONFIG_PROFILING is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHED_INFO is not set
# CONFIG_SWAP is not set
# CONFIG_TASKSTATS is not set
# CONFIG_ZRAM is not set
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
# CONFIG_ARCH_MULTIPLATFORM is not set
# CONFIG_VMAP_STACK is not set
# CONFIG_HARDEN_BRANCH_PREDICTOR is not set
# CONFIG_HARDEN_BRANCH_HISTORY is not set
# CONFIG_COMPACTION is not set
# CONFIG_MIGRATION is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_HZ_PERIODIC=y
CONFIG_HZ_1000=y
CONFIG_PREEMPT_RT=y
CONFIG_VDSO=y

View File

@@ -313,6 +313,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576s-tablet-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-dsi-dsc-MV2100UZ1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-8lanes-M280DCA.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-8lanes-TPM270WR1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-NE160QAM-NX1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-edp-NV140QUM-N61.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-evb1-lp4-v10-hdmi2dp.dtb
@@ -391,12 +392,16 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-fastboot-spi-nor.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v10-spi-nor.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v11.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v11-dual-4k.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v11-fastboot-emmc.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v11-fastboot-spi-nand.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v11-fastboot-spi-nor.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb1-v11-spi-nor.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-aov-dual-cam.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-dv.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-mcu-k350c4516t.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-rgb-Q7050ITH2641AA1T.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-sii9022-bt1120-to-hdmi.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb2-v10-tb-400w.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb3-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-evb4-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rv1126b-iotest-v10.dtb

View File

@@ -164,6 +164,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&rk809 1>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio1 RK_PC3 GPIO_ACTIVE_LOW>;

View File

@@ -24,6 +24,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS2";
//wifi-bt-power-toggle;
uart_rts-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";

View File

@@ -22,6 +22,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS2";
//wifi-bt-power-toggle;
uart_rts-gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";

View File

@@ -52,6 +52,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS2";
//wifi-bt-power-toggle;
uart_rts-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";

View File

@@ -24,6 +24,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS2";
//wifi-bt-power-toggle;
uart_rts-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";

View File

@@ -53,6 +53,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS2";
//wifi-bt-power-toggle;
uart_rts-gpios = <&gpio1 RK_PB2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";

View File

@@ -55,6 +55,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS2";
uart_rts-gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart2m0_rtsn>;

View File

@@ -438,6 +438,7 @@
};
&wireless_bluetooth {
bt_port = "/dev/ttyS1";
uart_rts-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart1m1_rtsn>;

View File

@@ -620,6 +620,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -506,6 +506,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -282,6 +282,7 @@
&wireless_bluetooth {
uart_rts-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_LOW>;
bt_port = "/dev/ttyS1";
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart1m1_rtsn>;
pinctrl-1 = <&uart1_gpios>;

View File

@@ -609,6 +609,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -634,6 +634,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -348,6 +348,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -497,6 +497,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -587,6 +587,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&pmucru CLK_RTC_32K>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -556,6 +556,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -444,6 +444,7 @@
&wireless_bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS1";
clocks = <&pmucru CLK_RTC_32K>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -367,6 +367,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&rk809 1>;
clock-names = "ext_clock";
//wifi-bt-power-toggle;

View File

@@ -194,6 +194,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;

View File

@@ -208,6 +208,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;

View File

@@ -50,6 +50,10 @@
};
&ebc {
pinctrl-names = "default", "sleep";
pinctrl-0 = <&vo_ebc_pins>;
pinctrl-1 = <&vo_ebc_sleep>;
status = "okay";
};

View File

@@ -207,6 +207,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart4m1_rtsn>;

View File

@@ -88,7 +88,6 @@
&edp {
force-hpd;
support-psr;
status = "okay";
ports {

View File

@@ -5817,6 +5817,57 @@
<3 RK_PD7 2 &pcfg_pull_none>;
};
/omit-if-no-ref/
vo_ebc_sleep: vo_ebc-sleep {
rockchip,pins =
/* vo_ebc_gdclk */
<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_gdoe */
<3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_gdsp */
<3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sdce0 */
<3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sdclk */
<3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo0 */
<3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo1 */
<3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo2 */
<3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo3 */
<3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo4 */
<3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo5 */
<3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo6 */
<3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo7 */
<3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo8 */
<3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo9 */
<3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo10 */
<3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo11 */
<3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo12 */
<3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo13 */
<3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo14 */
<3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sddo15 */
<3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sdle */
<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_down>,
/* vo_ebc_sdoe */
<3 RK_PD7 RK_FUNC_GPIO &pcfg_pull_down>;
};
/omit-if-no-ref/
vo_ebc_extern: vo_ebc-extern {
rockchip,pins =

View File

@@ -254,6 +254,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart4m1_rtsn>;

View File

@@ -173,6 +173,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart4m1_rtsn>;

View File

@@ -207,6 +207,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart4m1_rtsn>;

View File

@@ -261,6 +261,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS4";
uart_rts-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default", "rts_gpio";
pinctrl-0 = <&uart4m1_rtsn>;

View File

@@ -0,0 +1,308 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*
*/
/dts-v1/;
#include "rk3588-evb1-lp4.dtsi"
#include "rk3588-evb1-imx415.dtsi"
#include "rk3588-android.dtsi"
/ {
model = "Rockchip RK3588 EVB1 LP4 V10 Board + RK3588 EDP 8LANES V10 Ext Board";
compatible = "rockchip,rk3588-evb1-lp4-v10-edp-8lanes-TPM270WR1", "rockchip,rk3588";
vcc3v3_edp_bl: vcc3v3-edp-bl {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_edp_bl";
regulator-boot-on;
regulator-always-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
gpio = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
};
vcc3v3_edp: vcc3v3-edp {
compatible = "regulator-fixed";
regulator-name = "vcc3v3_edp";
regulator-boot-on;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-high;
gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc12v_dcin>;
};
};
&bt_sco {
status = "okay";
};
&bt_sound {
status = "okay";
};
&dsi0 {
status = "disabled";
};
&edp0 {
force-hpd;
status = "okay";
rockchip,dual-channel;
rockchip,data-swap;
ports {
port@1 {
reg = <1>;
edp0_out_panel: endpoint {
remote-endpoint = <&panel_in_edp0>;
};
};
};
};
&edp0_in_vp0 {
status = "okay";
};
&edp0_in_vp1 {
status = "disabled";
};
&edp0_in_vp2 {
status = "disabled";
};
&edp1 {
force-hpd;
status = "okay";
ports {
port@1 {
reg = <1>;
edp1_out_panel: endpoint {
remote-endpoint = <&panel_in_edp1>;
};
};
};
};
&edp1_in_vp0 {
status = "okay";
};
&edp1_in_vp1 {
status = "disabled";
};
&edp1_in_vp2 {
status = "disabled";
};
&hdmi0 {
status = "disabled";
};
&hdmi0_in_vp0 {
status = "disabled";
};
&hdmi0_sound {
status = "disabled";
};
&hdmi1 {
status = "disabled";
};
&hdmi1_in_vp1 {
status = "disabled";
};
&hdmi1_sound {
status = "disabled";
};
&hdptxphy0 {
status = "okay";
};
&hdptxphy1 {
status = "okay";
};
&hdptxphy_hdmi0 {
status = "disabled";
};
&hdptxphy_hdmi1 {
status = "disabled";
};
&i2s2_2ch {
status = "okay";
};
&pcie2x1l0 {
status = "disabled";
};
&pcie3x4 {
status = "disabled";
};
&route_dsi0 {
status = "disabled";
};
&route_edp0 {
status = "disabled";
connect = <&vp0_out_edp0>;
};
&route_edp1 {
status = "disabled";
connect = <&vp0_out_edp1>;
};
&route_hdmi0 {
status = "disabled";
};
&route_hdmi1 {
status = "disabled";
};
&spi0 {
pinctrl-names = "default";
pinctrl-0 = <&spi0m1_cs1 &spi0m1_pins>;
rockchip,poll-only;
status = "okay";
panel-edp@1 {
compatible = "rockchip,dimming-panel";
reg = <1>;
spi-max-frequency = <10000000>;
lden-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
blen-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
sync-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>;
dbcl-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
backlight = <&backlight>;
power-supply = <&vcc3v3_edp>;
enable-gpios = <&gpio4 RK_PC1 GPIO_ACTIVE_HIGH>;
prepare-delay-ms = <120>;
enable-delay-ms = <120>;
unprepare-delay-ms = <120>;
disable-delay-ms = <120>;
hzone-num = <48>;
vzone-num = <24>;
brightness-max = <255>;
brightness-min = <0>;
brightness-bpc = <8>;
command-header = [
aa // indicator
81 // command
00 // hdr on/off
0c // sdr current
20 // hdr current
00 // reserve
];
command-tail = [
00 // checknum
00 // end
];
/*
* The demo configs for 16bpc:
* brightness-bpc = <16>;
* command-header = [
* 00 aa // indicator
* 00 81 // command
* 00 00 // hdr on/off
* 00 0c // sdr current
* 00 20 // hdr current
* 00 00 // reserve
* ];
* command-tail = [
* 00 00 // checknum
* 00 00 // end
* ];
*/
status = "okay";
display-timings {
native-mode = <&timing_4kp60_dimming>;
timing_4kp60_dimming: timing2 {
clock-frequency = <528000000>;
hactive = <3840>;
vactive = <2160>;
hfront-porch = <60>;
hsync-len = <40>;
hback-porch = <60>;
vfront-porch = <15>;
vsync-len = <10>;
vback-porch = <15>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
timing_4kp144_dimming: timing3 {
clock-frequency = <1267200000>;
hactive = <3840>;
vactive = <2160>;
hfront-porch = <60>;
hsync-len = <40>;
hback-porch = <60>;
vfront-porch = <15>;
vsync-len = <10>;
vback-porch = <15>;
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_edp0: endpoint {
remote-endpoint = <&edp0_out_panel>;
};
};
port@1 {
reg = <1>;
panel_in_edp1: endpoint {
remote-endpoint = <&edp1_out_panel>;
};
};
};
};
};
&vop {
assigned-clocks = <&cru ACLK_VOP>;
assigned-clock-rates = <800000000>;
};
&vp0 {
assigned-clocks = <&cru DCLK_VOP0_SRC>;
assigned-clock-parents = <&cru PLL_V0PLL>;
};
&vp2 {
/delete-property/ assigned-clocks;
/delete-property/ assigned-clock-parents;
};

View File

@@ -75,7 +75,6 @@
&edp0 {
force-hpd;
support-psr;
status = "okay";
ports {

View File

@@ -214,6 +214,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;

View File

@@ -171,6 +171,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS9";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;

View File

@@ -175,6 +175,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;

View File

@@ -238,6 +238,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS7";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;

View File

@@ -250,6 +250,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS9";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;

View File

@@ -96,6 +96,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS9";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;

View File

@@ -108,6 +108,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS9";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;

View File

@@ -494,6 +494,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS7";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;

View File

@@ -178,6 +178,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS9";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio4 RK_PC4 GPIO_ACTIVE_LOW>;

View File

@@ -216,6 +216,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;

View File

@@ -199,6 +199,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;

View File

@@ -180,6 +180,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS8";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;

View File

@@ -296,6 +296,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS7";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
@@ -415,7 +416,6 @@
};
&edp0 {
support-psr;
force-hpd;
status = "okay";

View File

@@ -293,6 +293,7 @@
wireless_bluetooth: wireless-bluetooth {
compatible = "bluetooth-platdata";
bt_port = "/dev/ttyS7";
clocks = <&hym8563>;
clock-names = "ext_clock";
uart_rts-gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
@@ -362,7 +363,6 @@
};
&edp0 {
support-psr;
force-hpd;
status = "okay";
};

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b-evb1-v10-fastboot-emmc.dts"
#include "rv1126b-evb1-v11.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V11 Arm64 Fastboot Board";
compatible = "rockchip,rv1126b-evb1-v11-fastboot", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b-evb1-v10-fastboot-spi-nand.dts"
#include "rv1126b-evb1-v11.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V11 Arm64 Board";
compatible = "rockchip,rv1126b-evb1-v11-fastboot-spi-nand", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (40 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4b440000 (20 * 0x00100000)>;
};

View File

@@ -0,0 +1,24 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b-evb1-v10-fastboot-spi-nor.dts"
#include "rv1126b-evb1-v11.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V11 Arm64 Board";
compatible = "rockchip,rv1126b-evb1-v11-fastboot-spi-nor", "rockchip,rv1126b";
chosen {
bootargs = "loglevel=0 initcall_debug=0 earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 root=/dev/rd0 rootfstype=erofs rootflags=dax snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K";
};
};
&ramdisk_r {
reg = <0x48c40000 (20 * 0x00100000)>;
};
&ramdisk_c {
reg = <0x4a040000 (10 * 0x00100000)>;
};

View File

@@ -0,0 +1,13 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
#include "rv1126b-evb1-v10-spi-nor.dts"
#include "rv1126b-evb1-v11.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V11 Board";
compatible = "rockchip,rv1126b-evb1-v11-spi-nor", "rockchip,rv1126b";
};

View File

@@ -0,0 +1,91 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
*/
/dts-v1/;
#include "rv1126b.dtsi"
#include "rv1126b-evb.dtsi"
#include "rv1126b-evb2-v10.dtsi"
#include "rv1126b-evb-cam-csi0.dtsi"
/ {
model = "Rockchip RV1126B EVB1 V10 DV Board";
compatible = "rockchip,rv1126b-evb2-v10-dv", "rockchip,rv1126b";
chosen {
bootargs = "earlycon=uart8250,mmio32,0x20810000 console=ttyFIQ0 rw root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=32K isolcpus=3 nohz_full=3";
};
};
&gc8613 {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
/delete-property/ pwdn-gpios;
};
&gpio5 {
interrupt-affinity = <&cpu0>, <&cpu0>, <&cpu0>, <&cpu3>;
interrupt-pins = <0>,
<0>,
<0>,
<RK_PIN_TO_BIT(RK_PB0)>;
};
&imx415 {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
};
&imx586 {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
};
&pinctrl {
inv {
inv_int1: inv-int1 {
rockchip,pins =
<5 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
&rkfec {
status = "okay";
};
&rkfec_mmu {
status = "okay";
};
&rknpu {
status = "disabled";
};
&sc450ai {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_LOW>;
};
&sc850sl {
reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
};
&spi0 {
status = "okay";
max-freq = <24000000>;
pinctrl-names = "default";
pinctrl-0 = <&spi0m2_clk_pins &spi0m2_csn0_pins &inv_int1>;
icm42670: icm42670@0 {
compatible = "invensense,icm42670";
reg = <0x0>;
spi-max-frequency = <24000000>;
spi-cpha;
spi-cpol;
//vdd-supply = <&vcc_3v3_s0>;
int1-gpio = <&gpio5 RK_PB0 GPIO_ACTIVE_HIGH>;
interrupt-parent = <&gpio5>;
interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
status = "okay";
};
};
&uart2 {
status = "disabled";
};

View File

@@ -2708,85 +2708,85 @@
bt1120_pins: bt1120-pins {
rockchip,pins =
/* vo_lcdc_clk */
<5 RK_PD3 1 &pcfg_pull_none>,
<5 RK_PD3 1 &pcfg_pull_none_drv_level_4_75>,
/* vo_lcdc_d3 */
<5 RK_PA3 1 &pcfg_pull_none>,
<5 RK_PA3 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d4 */
<5 RK_PA4 1 &pcfg_pull_none>,
<5 RK_PA4 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d5 */
<5 RK_PA5 1 &pcfg_pull_none>,
<5 RK_PA5 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d6 */
<5 RK_PA6 1 &pcfg_pull_none>,
<5 RK_PA6 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d7 */
<5 RK_PA7 1 &pcfg_pull_none>,
<5 RK_PA7 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d10 */
<5 RK_PB2 1 &pcfg_pull_none>,
<5 RK_PB2 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d11 */
<5 RK_PB3 1 &pcfg_pull_none>,
<5 RK_PB3 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d12 */
<5 RK_PB4 1 &pcfg_pull_none>,
<5 RK_PB4 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d13 */
<5 RK_PB5 1 &pcfg_pull_none>,
<5 RK_PB5 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d14 */
<5 RK_PB6 1 &pcfg_pull_none>,
<5 RK_PB6 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d15 */
<5 RK_PB7 1 &pcfg_pull_none>,
<5 RK_PB7 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d19 */
<5 RK_PC3 1 &pcfg_pull_none>,
<5 RK_PC3 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d20 */
<5 RK_PC4 1 &pcfg_pull_none>,
<5 RK_PC4 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d21 */
<5 RK_PC5 1 &pcfg_pull_none>,
<5 RK_PC5 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d22 */
<5 RK_PC6 1 &pcfg_pull_none>,
<5 RK_PC6 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d23 */
<5 RK_PC7 1 &pcfg_pull_none>;
<5 RK_PC7 1 &pcfg_pull_none_drv_level_2_75>;
};
/omit-if-no-ref/
bt656_m0_pins: bt656-m0-pins {
rockchip,pins =
/* vo_lcdc_clk */
<5 RK_PD3 1 &pcfg_pull_none>,
<5 RK_PD3 1 &pcfg_pull_none_drv_level_4_75>,
/* vo_lcdc_d3 */
<5 RK_PA3 1 &pcfg_pull_none>,
<5 RK_PA3 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d4 */
<5 RK_PA4 1 &pcfg_pull_none>,
<5 RK_PA4 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d5 */
<5 RK_PA5 1 &pcfg_pull_none>,
<5 RK_PA5 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d6 */
<5 RK_PA6 1 &pcfg_pull_none>,
<5 RK_PA6 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d7 */
<5 RK_PA7 1 &pcfg_pull_none>,
<5 RK_PA7 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d10 */
<5 RK_PB2 1 &pcfg_pull_none>,
<5 RK_PB2 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d11 */
<5 RK_PB3 1 &pcfg_pull_none>,
<5 RK_PB3 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d12 */
<5 RK_PB4 1 &pcfg_pull_none>;
<5 RK_PB4 1 &pcfg_pull_none_drv_level_2_75>;
};
/omit-if-no-ref/
bt656_m1_pins: bt656-m1-pins {
rockchip,pins =
/* vo_lcdc_clk */
<5 RK_PD3 1 &pcfg_pull_none>,
<5 RK_PD3 1 &pcfg_pull_none_drv_level_4_75>,
/* vo_lcdc_d13 */
<5 RK_PB5 1 &pcfg_pull_none>,
<5 RK_PB5 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d14 */
<5 RK_PB6 1 &pcfg_pull_none>,
<5 RK_PB6 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d15 */
<5 RK_PB7 1 &pcfg_pull_none>,
<5 RK_PB7 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d19 */
<5 RK_PC3 1 &pcfg_pull_none>,
<5 RK_PC3 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d20 */
<5 RK_PC4 1 &pcfg_pull_none>,
<5 RK_PC4 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d21 */
<5 RK_PC5 1 &pcfg_pull_none>,
<5 RK_PC5 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d22 */
<5 RK_PC6 1 &pcfg_pull_none>,
<5 RK_PC6 1 &pcfg_pull_none_drv_level_2_75>,
/* vo_lcdc_d23 */
<5 RK_PC7 1 &pcfg_pull_none>;
<5 RK_PC7 1 &pcfg_pull_none_drv_level_2_75>;
};
/omit-if-no-ref/

View File

@@ -3337,24 +3337,24 @@
opp-microvolt-L1 = <875000 875000 1050000>;
};
opp-700000000 {
opp-supported-hw = <0xf7 0xffff>;
opp-supported-hw = <0xff 0xffff>;
opp-hz = /bits/ 64 <700000000>;
opp-microvolt = <850000 850000 1050000>;
opp-microvolt-L0 = <900000 900000 1050000>;
opp-microvolt-L1 = <875000 875000 1050000>;
};
opp-800000000 {
opp-supported-hw = <0xf7 0xffff>;
opp-supported-hw = <0xff 0xffff>;
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <925000 925000 1050000>;
};
opp-900000000 {
opp-supported-hw = <0xf7 0xffff>;
opp-supported-hw = <0xff 0xffff>;
opp-hz = /bits/ 64 <900000000>;
opp-microvolt = <975000 975000 1050000>;
};
opp-950000000 {
opp-supported-hw = <0xf7 0xffff>;
opp-supported-hw = <0xff 0xffff>;
opp-hz = /bits/ 64 <950000000>;
opp-microvolt = <975000 975000 1050000>;
opp-microvolt-L0 = <1000000 1000000 1050000>;
@@ -3377,8 +3377,8 @@
compatible = "rockchip,hw-decompress";
reg = <0x22100000 0x1000>;
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_DECOM>, <&cru DCLK_DECOM>, <&cru PCLK_DECOM>;
clock-names = "aclk", "dclk", "pclk";
clocks = <&cru ACLK_DECOM>, <&cru DCLK_DECOM>, <&cru PCLK_DECOM>, <&cru ACLK_RKMMU_DECOM>, <&cru HCLK_RKMMU_DECOM>;
clock-names = "aclk", "dclk", "pclk", "aclk_mmu", "hclk_mmu";
resets = <&cru SRST_DRESETN_DECOM>;
reset-names = "dresetn";
status = "disabled";

View File

@@ -8,6 +8,10 @@
/ {
};
&npu_opp_table {
rockchip,init-freq = <600000>;
};
&rgb {
/*
* RV1126 compatible pin output mode 0.

View File

@@ -158,6 +158,7 @@ CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_NVME=y
CONFIG_RK628_MISC=y
CONFIG_RK628_MISC_HDMITX=y
CONFIG_PCIE_FUNC_RKEP=y
CONFIG_SRAM=y
CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SR=y

View File

@@ -1,5 +1,25 @@
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
# CONFIG_ARM_PSCI_CPUIDLE is not set
# CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_CGROUP_SCHED is not set
# CONFIG_CPU_FREQ_TIMES is not set
CONFIG_NO_HZ_FULL=y
# CONFIG_CPU_FREQ_THERMAL is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_FTRACE is not set
# CONFIG_IRQ_TIME_ACCOUNTING is not set
# CONFIG_MALI_BIFROST_ENABLE_TRACE is not set
# CONFIG_MALI_BIFROST_SYSTEM_TRACE is not set
# CONFIG_PSI is not set
# CONFIG_PERF_EVENTS is not set
# CONFIG_PROFILING is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHED_INFO is not set
# CONFIG_SWAP is not set
# CONFIG_TASKSTATS is not set
# CONFIG_ZRAM is not set
# CONFIG_MIGRATION is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
CONFIG_JUMP_LABEL=y
CONFIG_HZ_PERIODIC=y
CONFIG_HZ_1000=y
CONFIG_PREEMPT_RT=y

View File

@@ -2280,6 +2280,11 @@ static void pl330_tasklet(struct tasklet_struct *t)
spin_lock_irqsave(&pch->lock, flags);
if (!pch->thread) {
spin_unlock_irqrestore(&pch->lock, flags);
return;
}
/* Pick up ripe tomatoes */
list_for_each_entry_safe(desc, _dt, &pch->work_list, node) {
if (desc->status == DONE) {

View File

@@ -191,7 +191,7 @@ static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp)
unsigned char psr_version;
int ret;
if (!device_property_read_bool(dp->dev, "support-psr"))
if (dp->plat_data->disable_psr)
return 0;
ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version);
@@ -819,37 +819,66 @@ static int analogix_dp_init_link_rate_table(struct analogix_dp_device *dp)
static int analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp,
u8 *bandwidth)
{
u32 max_link_rate;
u8 data;
int ret;
ret = drm_dp_dpcd_readb(&dp->aux, DP_EDP_DPCD_REV, &data);
if (ret == 1 && data >= DP_EDP_14) {
u32 max_link_rate;
/*
* For DP rev.1.1, Maximum link rate of Main Link lanes
* 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
* For DP rev.1.2, Maximum link rate of Main Link lanes
* 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
*/
ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data);
if (ret < 0)
return ret;
/* As the Table 4-23 in eDP 1.4 spec, the link rate table is required */
if (!dp->nr_link_rate_table) {
dev_info(dp->dev, "eDP version: 0x%02x supports link rate table\n", data);
*bandwidth = data;
ret = analogix_dp_init_link_rate_table(dp);
if (ret) {
dev_err(dp->dev, "failed to read link rate table: %d\n", ret);
return ret;
/*
* As the Table 4-24 in eDP 1.4 spec, the Sink device can only support
* Main-Link rate selection via SUPPORTED_LINK_RATES when the value of
* DPCD MAX_LINK_RATE is 00h. If MAX_LINK_RATE and SUPPORTED_LINK_RATES
* are both non-zero, the Sink device can support both methods.
*
* In practice, if MAX_LINK_RATE is not 00h and SUPPORTED_LINK_RATES
* contains non-zero values, sometimes the sink device can only support
* to set link rate via LINK_BW_SET. In such case, there will be errors
* if set the link rate read from SUPPORTED_LINK_RATES to LINK_RATE_SET.
*
* The panel vendor may explain this is to ensure the same Sink firmware
* remains compatible across different versions of the eDP spec. Or the
* Main-Link rate selection method has not been fully verified.
*
* In order to avoid these unexpected cases, MAX_LINK_RATE/LINK_BW_SET
* method will be selected first if MAX_LINK_RATE is non-zero for eDP
* panels that support 1.4 or higher.
*/
if (*bandwidth == 0) {
ret = drm_dp_dpcd_readb(&dp->aux, DP_EDP_DPCD_REV, &data);
if (ret == 1 && data >= DP_EDP_14) {
/*
* As the Table 4-23 in eDP 1.4 spec, the link rate table is required
* for eDP 1.4 Sink devices.
*/
if (!dp->nr_link_rate_table) {
dev_info(dp->dev, "eDP version: 0x%02x supports link rate table\n",
data);
ret = analogix_dp_init_link_rate_table(dp);
if (ret) {
dev_err(dp->dev, "failed to read link rate table: %d\n",
ret);
return ret;
}
}
max_link_rate = dp->link_rate_table[dp->nr_link_rate_table - 1];
*bandwidth = drm_dp_link_rate_to_bw_code(max_link_rate);
} else {
dev_err(dp->dev, "eDP version: 0x%02x MAX_LINK_RATE should be non-zero\n",
data);
return -EINVAL;
}
max_link_rate = dp->link_rate_table[dp->nr_link_rate_table - 1];
*bandwidth = drm_dp_link_rate_to_bw_code(max_link_rate);
} else {
/*
* For DP rev.1.1, Maximum link rate of Main Link lanes
* 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps
* For DP rev.1.2, Maximum link rate of Main Link lanes
* 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps
*/
ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LINK_RATE, &data);
if (ret < 0)
return ret;
*bandwidth = data;
}
return 0;

View File

@@ -2622,6 +2622,7 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
struct dw_hdmi_qp *hdmi =
container_of(connector, struct dw_hdmi_qp, connector);
struct dw_hdmi_qp *secondary = NULL;
struct drm_display_mode *mode;
enum drm_connector_status result, result_secondary;
mutex_lock(&hdmi->mutex);
@@ -2659,8 +2660,12 @@ out:
extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, true);
handle_plugged_change(hdmi, true);
} else {
if (!hdmi->next_bridge)
if (!hdmi->next_bridge) {
drm_connector_update_edid_property(&hdmi->connector, NULL);
list_for_each_entry(mode, &hdmi->connector.modes, head)
mode->status = MODE_STALE;
drm_mode_prune_invalid(hdmi->connector.dev, &hdmi->connector.modes, false);
}
extcon_set_state_sync(hdmi->extcon, EXTCON_DISP_HDMI, false);
handle_plugged_change(hdmi, false);
}
@@ -3405,7 +3410,8 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector,
drm_scdc_readb(hdmi->ddc, SCDC_TMDS_CONFIG, &val);
/* if plug out before hdmi bind, reset hdmi */
if (vmode->mtmdsclock >= 340000000 && vmode->mpixelclock <= 600000000 &&
!(val & SCDC_TMDS_BIT_CLOCK_RATIO_BY_40) && !hdmi->force_kernel_output)
!(val & SCDC_TMDS_BIT_CLOCK_RATIO_BY_40) && !hdmi->force_kernel_output &&
hdmi->initialized)
hdmi->logo_plug_out = true;
}
@@ -3761,6 +3767,8 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
mutex_lock(&hdmi->audio_mutex);
if (hdmi->plat_data->dclk_set)
hdmi->plat_data->dclk_set(data, true, hdmi->vp_id);
if (hdmi->plat_data->crtc_post_enable)
hdmi->plat_data->crtc_post_enable(data, bridge->encoder->crtc);
hdmi->dclk_en = true;
mutex_unlock(&hdmi->audio_mutex);
}
@@ -3768,9 +3776,6 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
if (link_cfg && link_cfg->frl_mode)
queue_work(hdmi->workqueue, &hdmi->flt_work);
if (hdmi->plat_data->crtc_post_enable)
hdmi->plat_data->crtc_post_enable(data, bridge->encoder->crtc);
dw_hdmi_qp_init_audio_infoframe(hdmi);
dw_hdmi_qp_audio_enable(hdmi);
hdmi_clk_regenerator_update_pixel_clock(hdmi);

View File

@@ -82,6 +82,15 @@ config ROCKCHIP_CDN_DP
RK3399 based SoC, you should select this
option.
config ROCKCHIP_DIMMING_PANEL
bool "Rockchip dimming panel support"
depends on SPI
default n
help
Choose this option to enable support for generic dimming panel
which supports to adjust the backlight brightness of different
zones.
config ROCKCHIP_DRM_TVE
bool "Rockchip TVE support"
depends on DRM_ROCKCHIP

View File

@@ -33,6 +33,7 @@ obj-$(CONFIG_ROCKCHIP_PANEL_NOTIFIER) += rockchip_panel_notifier.o
obj-$(CONFIG_ROCKCHIP_DW_HDCP2) += dw_hdcp2.o
obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o
obj-$(CONFIG_DRM_ROCKCHIP_RK618) += rk618/
obj-$(CONFIG_ROCKCHIP_DIMMING_PANEL) += rockchip_dimming_panel.o
rockchip_aux_client-y := rockchip_dp_mst_aux_client.o rockchip_dp_mst_aux_client_helper.o
obj-$(CONFIG_ROCKCHIP_DP_MST_AUX_CLIENT) += rockchip_aux_client.o

View File

@@ -28,6 +28,7 @@
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_simple_kms_helper.h>
#include "rockchip_drm_drv.h"
@@ -635,6 +636,38 @@ static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp)
return 0;
}
static void rockchip_dp_drm_self_refresh_helper_init(struct rockchip_dp_device *dp)
{
struct drm_encoder *encoder = &dp->encoder.encoder;
struct drm_crtc *crtc;
int ret;
if (!dp->plat_data.disable_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc)) {
ret = drm_self_refresh_helper_init(crtc);
if (ret)
dev_warn(dp->dev,
"Failed to init self refresh helper for crtc-%d\n",
drm_crtc_index(crtc));
}
}
}
}
static void rockchip_dp_drm_self_refresh_helper_cleanup(struct rockchip_dp_device *dp)
{
struct drm_encoder *encoder = &dp->encoder.encoder;
struct drm_crtc *crtc;
if (!dp->plat_data.disable_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc))
drm_self_refresh_helper_cleanup(crtc);
}
}
}
static int rockchip_dp_bind(struct device *dev, struct device *master,
void *data)
{
@@ -658,6 +691,8 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
if (ret)
goto err_unregister_audio_pdev;
rockchip_dp_drm_self_refresh_helper_init(dp);
return 0;
err_unregister_audio_pdev:
@@ -673,6 +708,7 @@ static void rockchip_dp_unbind(struct device *dev, struct device *master,
if (dp->audio_pdev)
platform_device_unregister(dp->audio_pdev);
rockchip_dp_drm_self_refresh_helper_cleanup(dp);
analogix_dp_unbind(dp->adp);
dp->encoder.encoder.funcs->destroy(&dp->encoder.encoder);
}
@@ -734,6 +770,7 @@ static int rockchip_dp_probe(struct platform_device *pdev)
dp->plat_data.convert_to_origin_mode = drm_mode_convert_to_origin_mode;
dp->plat_data.skip_connector = rockchip_dp_skip_connector(bridge);
dp->plat_data.bridge = bridge;
dp->plat_data.disable_psr = device_property_read_bool(dp->dev, "rockchip,disable-psr");
ret = rockchip_dp_of_probe(dp);
if (ret < 0)

View File

@@ -1036,23 +1036,36 @@ rockchip_hdmi_find_by_id(struct device_driver *drv, unsigned int id)
return dev_get_drvdata(dev);
}
static bool rockchip_hdmi_check_dsc_rate_supported(struct rockchip_hdmi *hdmi,
u64 tmdsclk, u8 bpp)
{
u64 data_rate, dsc_rate;
u64 frl_rate, dsc_frl_rate;
frl_rate = (u64)hdmi->hdmi21_data.max_lanes *
hdmi->hdmi21_data.max_frl_rate_per_lane * 1000000000;
dsc_frl_rate = (u64)hdmi->hdmi21_data.dsc_cap.max_lanes *
hdmi->hdmi21_data.dsc_cap.max_frl_rate_per_lane * 1000000000;
data_rate = (u64)tmdsclk * bpp;
data_rate = DIV_ROUND_UP_ULL(data_rate * 18, 16);
/* compression ratio needs to be greater than 0.375. */
dsc_rate = DIV_ROUND_UP_ULL(data_rate * 9, 24);
if ((data_rate > frl_rate) && (dsc_rate > dsc_frl_rate))
return true;
return false;
}
static bool rockchip_hdmi_if_dsc_enable(struct rockchip_hdmi *hdmi, unsigned int tmdsclk)
{
u64 data_rate;
u64 frl_rate = (u64)hdmi->link_cfg.frl_lanes * hdmi->link_cfg.rate_per_lane * 1000000;
u8 bpp = hdmi_bus_fmt_color_depth(hdmi->bus_format) * 3;
/* rk3588 dsc can't support yuv420/422 dsc */
if (hdmi_bus_fmt_is_yuv420(hdmi->bus_format) || hdmi_bus_fmt_is_yuv422(hdmi->bus_format))
return false;
data_rate = (u64)tmdsclk * bpp;
data_rate = DIV_ROUND_UP_ULL(data_rate * 18, 16);
if (data_rate > frl_rate)
return true;
return false;
return rockchip_hdmi_check_dsc_rate_supported(hdmi, tmdsclk, bpp);
}
static void hdmi_select_link_config(struct rockchip_hdmi *hdmi,
@@ -1092,7 +1105,7 @@ static void hdmi_select_link_config(struct rockchip_hdmi *hdmi,
max_dsc_rate_per_lane =
hdmi->hdmi21_data.dsc_cap.max_frl_rate_per_lane;
if (rockchip_hdmi_if_dsc_enable(hdmi, tmdsclk)) {
if (rockchip_hdmi_if_dsc_enable(hdmi, tmdsclk * 1000)) {
hdmi->link_cfg.dsc_mode = true;
hdmi->link_cfg.frl_lanes = max_dsc_lanes;
hdmi->link_cfg.rate_per_lane = max_dsc_rate_per_lane;
@@ -2419,6 +2432,7 @@ dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state,
bool support_dc = false;
bool sink_is_hdmi = true;
bool yuv422_out = false;
bool dsc_rate_supported;
u32 max_tmds_clock = info->max_tmds_clock;
int output_eotf;
@@ -2537,9 +2551,14 @@ dw_hdmi_rockchip_select_output(struct drm_connector_state *conn_state,
DRM_MODE_FLAG_3D_FRAME_PACKING)
pixclock *= 2;
tmdsclock = hdmi_get_tmdsclock(hdmi, mode.clock * 1000);
dsc_rate_supported =
rockchip_hdmi_check_dsc_rate_supported(hdmi, tmdsclock, color_depth * 3);
if (drm_mode_is_420_only(info, &mode) ||
(hdmi->is_hdmi_qp && mode.clock > 1188000 &&
(*color_format == RK_IF_FORMAT_YCBCR422 || hdmi->force_disable_dsc)))
(*color_format == RK_IF_FORMAT_YCBCR422 || hdmi->force_disable_dsc ||
!dsc_rate_supported)))
*color_format = RK_IF_FORMAT_YCBCR420;
if (!sink_is_hdmi) {

View File

@@ -0,0 +1,873 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
* Author: Damon Ding <damon.ding@rock-chips.com>
*/
#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/rockchip-panel-notifier.h>
#include <linux/spi/spi.h>
#include <video/display_timing.h>
#include <video/of_display_timing.h>
#include <video/videomode.h>
#include <drm/drm_crtc.h>
#include <drm/drm_vblank.h>
#include "rockchip_drm_drv.h"
#define MAX_DIMMING_PANELS 8
static DECLARE_BITMAP(allocated_dimming_panels, MAX_DIMMING_PANELS);
static struct class *rockchip_dimming_class;
struct rockchip_dimming_panel {
struct device *dev;
struct device *dimming_dev;
struct drm_crtc *crtc;
struct drm_panel base;
uint8_t id;
const struct drm_display_mode *modes;
uint32_t num_modes;
/** @delay: Structure containing various delay values for this panel. */
/**
* @prepare: the time (in milliseconds) that it takes for the panel to
* become ready and start receiving video data
* @hpd_absent_delay: Add this to the prepare delay if we know Hot
* Plug Detect isn't used.
* @enable: the time (in milliseconds) that it takes for the panel to
* display the first valid frame after starting to receive
* video data
* @disable: the time (in milliseconds) that it takes for the panel to
* turn the display off (no content is visible)
* @unprepare: the time (in milliseconds) that it takes for the panel
* to power itself down completely
* @reset: the time (in milliseconds) that it takes for the panel
* to reset itself completely
* @init: the time (in milliseconds) that it takes for the panel to
* send init command sequence after reset deassert
* @vsync_hold: the time (in microseconds) that it takes for the panel to
* hold the vsync signal high
* @vysnc_back: the time (in microseconds) that it takes for the panel to
* delay the vsync signal
*/
struct {
uint32_t prepare;
uint32_t enable;
uint32_t disable;
uint32_t unprepare;
uint32_t reset;
uint32_t init;
uint32_t vsync_hold;
uint32_t vsync_back;
} delay;
struct regulator *supply;
struct gpio_desc *enable_gpio;
struct gpio_desc *reset_gpio;
struct gpio_desc *lden_gpio;
struct gpio_desc *blen_gpio;
struct gpio_desc *sync_gpio;
struct gpio_desc *dbcl_gpio;
struct kthread_worker *dimming_worker;
struct kthread_delayed_work dimming_delayed_work;
struct rockchip_panel_notifier panel_notifier;
struct rockchip_drm_sub_dev sub_dev;
/** @bus_format: See MEDIA_BUS_FMT_... defines. */
uint32_t bus_format;
/** @bus_flags: See DRM_BUS_FLAG_... defines. */
uint32_t bus_flags;
void *data;
bool enabled;
bool prepared;
uint32_t checksum;
uint32_t hzone_num;
uint32_t vzone_num;
uint32_t zone_max;
uint32_t brightness_max;
uint32_t brightness_min;
uint32_t brightness_bpc;
uint32_t cmd_element_size;
uint32_t cmd_header_len;
uint32_t cmd_tail_len;
uint8_t *cmd_header;
uint8_t *cmd_tail;
};
static ssize_t crtc_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->crtc ? dimming_panel->crtc->base.id : 0);
}
static ssize_t checksum_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->checksum);
}
static ssize_t hzone_num_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->hzone_num);
}
static ssize_t vzone_num_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->vzone_num);
}
static ssize_t zone_max_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->zone_max);
}
static ssize_t brightness_max_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->brightness_max);
}
static ssize_t brightness_min_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->brightness_min);
}
static ssize_t brightness_bpc_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct spi_device *spi = dev_get_drvdata(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
return sprintf(buf, "%d\n", dimming_panel->brightness_bpc);
}
static DEVICE_ATTR_RO(crtc_id);
static DEVICE_ATTR_RO(checksum);
static DEVICE_ATTR_RO(hzone_num);
static DEVICE_ATTR_RO(vzone_num);
static DEVICE_ATTR_RO(zone_max);
static DEVICE_ATTR_RO(brightness_max);
static DEVICE_ATTR_RO(brightness_min);
static DEVICE_ATTR_RO(brightness_bpc);
/*
* The above attributes can be read via the following paths:
* (X means the index of dimming panel device)
* /sys/class/dimming/dimming_X/crtc_id
* /sys/class/dimming/dimming_X/checksum
* /sys/class/dimming/dimming_X/hzone_num
* /sys/class/dimming/dimming_X/vzone_num
* /sys/class/dimming/dimming_X/zone_max
* /sys/class/dimming/dimming_X/brightness_max
* /sys/class/dimming/dimming_X/brightness_min
* /sys/class/dimming/dimming_X/brightness_bpc
*/
static struct attribute *rockchip_dimming_attrs[] = {
&dev_attr_crtc_id.attr,
&dev_attr_checksum.attr,
&dev_attr_hzone_num.attr,
&dev_attr_vzone_num.attr,
&dev_attr_zone_max.attr,
&dev_attr_brightness_max.attr,
&dev_attr_brightness_min.attr,
&dev_attr_brightness_bpc.attr,
NULL,
};
static struct attribute_group rockchip_dimming_attr_group = {
.attrs = rockchip_dimming_attrs,
};
static inline void rockchip_dimming_panel_msleep(uint32_t msecs)
{
usleep_range(msecs * 1000, msecs * 1000 + 100);
}
static inline struct rockchip_dimming_panel *to_rockchip_dimming_panel(struct drm_panel *panel)
{
return container_of(panel, struct rockchip_dimming_panel, base);
}
static bool of_child_node_is_present(const struct device_node *node, const char *name)
{
struct device_node *child;
child = of_get_child_by_name(node, name);
of_node_put(child);
return !!child;
}
static int rockchip_dimming_panel_spi_write_data(struct device *dev, const void *data)
{
struct spi_device *spi = to_spi_device(dev);
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
struct spi_transfer t;
struct spi_message m;
uint32_t offset = 0;
uint32_t element_bytes = dimming_panel->brightness_bpc / 8;
uint16_t checksum = 0;
uint8_t *txbuf = NULL;
int len;
int i = 0, ret;
t.len = dimming_panel->cmd_element_size * element_bytes;
t.bits_per_word = dimming_panel->brightness_bpc;
txbuf = kzalloc(t.len * element_bytes, GFP_KERNEL);
if (!txbuf)
return -ENOMEM;
/* set sequence header */
memcpy(txbuf, dimming_panel->cmd_header, dimming_panel->cmd_header_len);
/* set brightness data */
offset += dimming_panel->cmd_header_len;
memcpy(txbuf + offset, data, dimming_panel->zone_max * element_bytes);
/* calculate magic code */
len = dimming_panel->cmd_header_len + dimming_panel->zone_max * element_bytes;
for (i = 0; i < len; i++) {
if (dimming_panel->brightness_bpc == 16) {
checksum ^= (uint16_t)(txbuf[i] << 8 | txbuf[i + 1]);
i++;
} else {
checksum ^= txbuf[i];
}
}
/* set magic code */
offset += dimming_panel->zone_max * element_bytes;
memcpy(txbuf + offset, &checksum, element_bytes);
dimming_panel->checksum = checksum;
/* set sequence tail */
offset += element_bytes;
memcpy(txbuf + offset, dimming_panel->cmd_tail,
dimming_panel->cmd_tail_len - element_bytes);
t.tx_buf = txbuf;
spi_message_init(&m);
spi_message_add_tail(&t, &m);
ret = spi_sync(spi, &m);
kfree(txbuf);
return ret;
}
static void dimming_delayed_work_func(struct kthread_work *work)
{
struct rockchip_dimming_panel *dimming_panel =
container_of(work, struct rockchip_dimming_panel, dimming_delayed_work.work);
struct device *dev = dimming_panel->base.dev;
struct drm_crtc *crtc = dimming_panel->crtc;
struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
const struct drm_display_mode *mode = &dimming_panel->modes[0];
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
unsigned int delay_ms = 0;
uint32_t timeout = DIV_ROUND_CLOSEST_ULL(1000, drm_mode_vrefresh(mode));
uint32_t element_bytes = dimming_panel->brightness_bpc / 8;
uint64_t last;
int pipe = 0;
int ret = 0;
if (!vcstate->dimming_changed || !vcstate->dimming_data || !vcstate->dimming_data->data) {
dev_dbg(dev, "dimming data may be unprepared\n");
delay_ms = timeout;
goto out;
}
vcstate->dimming_changed = false;
memcpy(dimming_panel->data, vcstate->dimming_data->data,
dimming_panel->zone_max * element_bytes);
ret = drm_crtc_vblank_get(crtc);
if (ret) {
dev_err(dev, "failed to get vblank on crtc-%d\n", pipe);
delay_ms = timeout;
goto out;
}
delay_ms = 0;
last = drm_crtc_vblank_count(crtc);
ret = wait_event_timeout(vblank->queue, last != drm_crtc_vblank_count(crtc),
msecs_to_jiffies(timeout));
drm_crtc_vblank_put(crtc);
if (!ret) {
dev_err(dev, "failed to wait for vblank on crtc-%d\n", pipe);
goto out;
}
gpiod_direction_output(dimming_panel->sync_gpio, 1);
udelay(dimming_panel->delay.vsync_hold);
gpiod_direction_output(dimming_panel->sync_gpio, 0);
udelay(dimming_panel->delay.vsync_back);
ret = rockchip_dimming_panel_spi_write_data(dimming_panel->base.dev,
dimming_panel->data);
if (ret)
dev_err(dev, "failed to write dimming data on crtc-%d\n", pipe);
out:
kthread_queue_delayed_work(dimming_panel->dimming_worker,
&dimming_panel->dimming_delayed_work,
msecs_to_jiffies(delay_ms));
};
static int rockchip_dimming_panel_regulator_enable(struct rockchip_dimming_panel *dimming_panel)
{
int ret;
ret = regulator_enable(dimming_panel->supply);
if (ret < 0)
return ret;
return 0;
}
static int rockchip_dimming_panel_regulator_disable(struct rockchip_dimming_panel *dimming_panel)
{
regulator_disable(dimming_panel->supply);
return 0;
}
static int rockchip_dimming_panel_prepare(struct drm_panel *panel)
{
struct rockchip_dimming_panel *dimming_panel = to_rockchip_dimming_panel(panel);
int ret;
if (dimming_panel->prepared)
return 0;
ret = rockchip_dimming_panel_regulator_enable(dimming_panel);
if (ret < 0) {
dev_err(panel->dev, "failed to enable regulator: %d\n", ret);
return ret;
}
gpiod_direction_output(dimming_panel->lden_gpio, 0);
gpiod_direction_output(dimming_panel->blen_gpio, 1);
gpiod_direction_output(dimming_panel->dbcl_gpio, 1);
gpiod_direction_output(dimming_panel->sync_gpio, 0);
gpiod_direction_output(dimming_panel->enable_gpio, 1);
if (dimming_panel->delay.prepare)
rockchip_dimming_panel_msleep(dimming_panel->delay.prepare);
gpiod_direction_output(dimming_panel->reset_gpio, 1);
if (dimming_panel->delay.reset)
rockchip_dimming_panel_msleep(dimming_panel->delay.reset);
gpiod_direction_output(dimming_panel->reset_gpio, 0);
if (dimming_panel->delay.init)
rockchip_dimming_panel_msleep(dimming_panel->delay.init);
dimming_panel->prepared = true;
return 0;
}
static int rockchip_dimming_panel_enable(struct drm_panel *panel)
{
struct rockchip_dimming_panel *dimming_panel = to_rockchip_dimming_panel(panel);
if (dimming_panel->enabled)
return 0;
if (dimming_panel->delay.enable)
rockchip_dimming_panel_msleep(dimming_panel->delay.enable);
gpiod_direction_output(dimming_panel->lden_gpio, 1);
usleep_range(10 * 1000, 10 * 1000 + 500);
kthread_queue_delayed_work(dimming_panel->dimming_worker,
&dimming_panel->dimming_delayed_work, 0);
dimming_panel->enabled = true;
/*
* notify other devices (such as TP) to perform the action after the
* panel is enabled.
*/
rockchip_panel_notifier_call_chain(&dimming_panel->panel_notifier,
PANEL_ENABLED, NULL);
return 0;
}
static int rockchip_dimming_panel_disable(struct drm_panel *panel)
{
struct rockchip_dimming_panel *dimming_panel = to_rockchip_dimming_panel(panel);
/*
* notify other devices (such as TP) to perform the action before the
* panel is disabled.
*/
rockchip_panel_notifier_call_chain(&dimming_panel->panel_notifier,
PANEL_PRE_DISABLE, NULL);
if (!dimming_panel->enabled)
return 0;
if (dimming_panel->delay.disable)
rockchip_dimming_panel_msleep(dimming_panel->delay.disable);
kthread_cancel_delayed_work_sync(&dimming_panel->dimming_delayed_work);
gpiod_direction_output(dimming_panel->lden_gpio, 0);
dimming_panel->enabled = false;
return 0;
}
static int rockchip_dimming_panel_unprepare(struct drm_panel *panel)
{
struct rockchip_dimming_panel *dimming_panel = to_rockchip_dimming_panel(panel);
/* Unpreparing when already unprepared is a no-op */
if (!dimming_panel->prepared)
return 0;
gpiod_direction_output(dimming_panel->reset_gpio, 1);
gpiod_direction_output(dimming_panel->enable_gpio, 0);
rockchip_dimming_panel_regulator_disable(dimming_panel);
if (dimming_panel->delay.unprepare)
rockchip_dimming_panel_msleep(dimming_panel->delay.unprepare);
dimming_panel->prepared = false;
return 0;
}
static int rockchip_dimming_panel_find_possible_crtc(struct drm_panel *panel,
struct drm_connector *connector)
{
struct rockchip_dimming_panel *dimming_panel = to_rockchip_dimming_panel(panel);
struct drm_encoder *encoder;
struct drm_crtc *crtc;
drm_connector_for_each_possible_encoder(connector, encoder)
break;
if (!encoder)
return -EINVAL;
drm_for_each_crtc(crtc, encoder->dev) {
if (crtc->index == ffs(encoder->possible_crtcs) - 1) {
dimming_panel->crtc = crtc;
return 0;
}
}
return -EINVAL;
}
static int rockchip_dimming_panel_get_modes(struct drm_panel *panel,
struct drm_connector *connector)
{
struct rockchip_dimming_panel *dimming_panel = to_rockchip_dimming_panel(panel);
struct drm_display_mode *mode;
uint32_t i, num = 0;
if (rockchip_dimming_panel_find_possible_crtc(panel, connector))
return 0;
for (i = 0; i < dimming_panel->num_modes; i++) {
const struct drm_display_mode *m = &dimming_panel->modes[i];
mode = drm_mode_duplicate(connector->dev, m);
if (!mode) {
dev_err(dimming_panel->base.dev, "failed to add mode %ux%u@%u\n",
m->hdisplay, m->vdisplay,
drm_mode_vrefresh(m));
continue;
}
mode->type |= DRM_MODE_TYPE_DRIVER;
if (dimming_panel->num_modes == 1)
mode->type |= DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode);
drm_mode_probed_add(connector, mode);
num++;
}
if (dimming_panel->bus_format)
drm_display_info_set_bus_formats(&connector->display_info,
&dimming_panel->bus_format, 1);
if (dimming_panel->bus_flags)
connector->display_info.bus_flags = dimming_panel->bus_flags;
return num;
}
static const struct drm_panel_funcs rockchip_dimming_panel_funcs = {
.prepare = rockchip_dimming_panel_prepare,
.enable = rockchip_dimming_panel_enable,
.disable = rockchip_dimming_panel_disable,
.unprepare = rockchip_dimming_panel_unprepare,
.get_modes = rockchip_dimming_panel_get_modes,
};
static int rockchip_dimming_panel_loader_protect(struct rockchip_drm_sub_dev *sub_dev, bool on)
{
struct rockchip_dimming_panel *dimming_panel = container_of(sub_dev,
struct rockchip_dimming_panel,
sub_dev);
int ret;
if (on) {
ret = rockchip_dimming_panel_regulator_enable(dimming_panel);
if (ret < 0) {
dev_err(dimming_panel->base.dev, "failed to enable regulator: %d\n", ret);
return ret;
}
kthread_queue_delayed_work(dimming_panel->dimming_worker,
&dimming_panel->dimming_delayed_work, 0);
dimming_panel->enabled = true;
dimming_panel->prepared = true;
} else {
dimming_panel->enabled = false;
dimming_panel->prepared = false;
kthread_cancel_delayed_work_sync(&dimming_panel->dimming_delayed_work);
rockchip_dimming_panel_regulator_disable(dimming_panel);
}
return 0;
}
static int rockchip_dimming_panel_of_get_data(struct rockchip_dimming_panel *dimming_panel)
{
struct device *dev = dimming_panel->dev;
struct device_node *np;
struct drm_display_mode *mode;
const void *data;
uint32_t bus_flags;
uint32_t element_bytes;
int len;
int ret;
dimming_panel->supply = devm_regulator_get(dev, "power");
if (IS_ERR(dimming_panel->supply))
return dev_err_probe(dev, PTR_ERR(dimming_panel->supply),
"failed to get power regulator\n");
dimming_panel->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_ASIS);
if (IS_ERR(dimming_panel->enable_gpio))
return dev_err_probe(dev, PTR_ERR(dimming_panel->enable_gpio),
"failed to get enable GPIO\n");
dimming_panel->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS);
if (IS_ERR(dimming_panel->reset_gpio))
return dev_err_probe(dev, PTR_ERR(dimming_panel->reset_gpio),
"failed to get reset GPIO\n");
dimming_panel->lden_gpio = devm_gpiod_get_optional(dev, "lden", GPIOD_ASIS);
if (IS_ERR(dimming_panel->lden_gpio))
return dev_err_probe(dev, PTR_ERR(dimming_panel->lden_gpio),
"failed to get lden GPIO\n");
dimming_panel->blen_gpio = devm_gpiod_get_optional(dev, "blen", GPIOD_ASIS);
if (IS_ERR(dimming_panel->blen_gpio)) {
return dev_err_probe(dev, PTR_ERR(dimming_panel->blen_gpio),
"failed to get blen GPIO\n");
}
dimming_panel->dbcl_gpio = devm_gpiod_get_optional(dev, "dbcl", GPIOD_ASIS);
if (IS_ERR(dimming_panel->dbcl_gpio))
return dev_err_probe(dev, PTR_ERR(dimming_panel->dbcl_gpio),
"failed to get dbcl GPIO\n");
dimming_panel->sync_gpio = devm_gpiod_get_optional(dev, "sync", GPIOD_ASIS);
if (IS_ERR(dimming_panel->sync_gpio))
return dev_err_probe(dev, PTR_ERR(dimming_panel->sync_gpio),
"failed to get sync GPIO\n");
np = dimming_panel->dev->of_node;
if (of_child_node_is_present(np, "display-timings")) {
mode = devm_kzalloc(dev, sizeof(*mode), GFP_KERNEL);
if (!mode)
return -ENOMEM;
if (!of_get_drm_display_mode(np, mode, &bus_flags, OF_USE_NATIVE_MODE)) {
dimming_panel->modes = mode;
dimming_panel->num_modes = 1;
dimming_panel->bus_flags = bus_flags;
of_property_read_u32(np, "bus-format", &dimming_panel->bus_format);
of_property_read_u32(np, "prepare-delay-ms", &dimming_panel->delay.prepare);
of_property_read_u32(np, "enable-delay-ms", &dimming_panel->delay.enable);
of_property_read_u32(np, "disable-delay-ms", &dimming_panel->delay.disable);
of_property_read_u32(np, "unprepare-delay-ms",
&dimming_panel->delay.unprepare);
of_property_read_u32(np, "reset-delay-ms", &dimming_panel->delay.reset);
of_property_read_u32(np, "init-delay-ms", &dimming_panel->delay.init);
of_property_read_u32(np, "vsync-hold-us", &dimming_panel->delay.vsync_hold);
of_property_read_u32(np, "vsync-back-us", &dimming_panel->delay.vsync_back);
} else {
devm_kfree(dev, mode);
}
}
/* Parameters to report */
ret = of_property_read_u32(np, "hzone-num", &dimming_panel->hzone_num);
if (ret)
return dev_err_probe(dev, ret, "failed to get horizontal zone number\n");
ret = of_property_read_u32(np, "vzone-num", &dimming_panel->vzone_num);
if (ret)
return dev_err_probe(dev, ret, "failed to get vertical zone number\n");
dimming_panel->zone_max = dimming_panel->hzone_num * dimming_panel->vzone_num;
ret = of_property_read_u32(np, "brightness-max", &dimming_panel->brightness_max);
if (ret)
return dev_err_probe(dev, ret, "failed to get brightness max value\n");
ret = of_property_read_u32(np, "brightness-min", &dimming_panel->brightness_min);
if (ret)
return dev_err_probe(dev, ret, "failed to get brightness min value\n");
ret = of_property_read_u32(np, "brightness-bpc", &dimming_panel->brightness_bpc);
if (ret)
return dev_err_probe(dev, ret, "failed to get brightness bpc value\n");
if (dimming_panel->brightness_bpc != 8 && dimming_panel->brightness_bpc != 16)
return dev_err_probe(dev, -EINVAL, "brightness bpc value should be 8 or 16\n");
element_bytes = dimming_panel->brightness_bpc / 8;
dimming_panel->data = devm_kzalloc(dev, element_bytes * dimming_panel->zone_max,
GFP_KERNEL);
if (!dimming_panel->data)
return -ENOMEM;
dimming_panel->cmd_element_size = dimming_panel->zone_max;
data = of_get_property(np, "command-header", &len);
if (data) {
dimming_panel->cmd_header = devm_kzalloc(dev, len, GFP_KERNEL);
if (!dimming_panel->cmd_header)
return -ENOMEM;
memcpy(dimming_panel->cmd_header, data, len);
dimming_panel->cmd_header_len = len;
}
dimming_panel->cmd_element_size += dimming_panel->cmd_header_len / element_bytes;
data = of_get_property(np, "command-tail", &len);
if (data) {
dimming_panel->cmd_tail = devm_kzalloc(dev, len, GFP_KERNEL);
if (!dimming_panel->cmd_tail)
return -ENOMEM;
memcpy(dimming_panel->cmd_tail, data, len);
dimming_panel->cmd_tail_len = len;
}
dimming_panel->cmd_element_size += dimming_panel->cmd_tail_len / element_bytes;
return 0;
}
static int rockchip_dimming_panel_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct device *dimming_dev;
struct rockchip_dimming_panel *dimming_panel;
int ret;
spi->bits_per_word = 8;
ret = spi_setup(spi);
if (ret < 0)
return dev_err_probe(dev, ret, "failed to setup spi\n");
dimming_panel = devm_kzalloc(dev, sizeof(*dimming_panel), GFP_KERNEL);
if (!dimming_panel)
return -ENOMEM;
dimming_panel->dev = dev;
ret = rockchip_dimming_panel_of_get_data(dimming_panel);
if (ret)
return dev_err_probe(dev, ret, "failed to get dimming panel configs\n");
dev_set_drvdata(dev, dimming_panel);
drm_panel_init(&dimming_panel->base, dev, &rockchip_dimming_panel_funcs,
DRM_MODE_CONNECTOR_Unknown);
ret = drm_panel_of_backlight(&dimming_panel->base);
if (ret)
return dev_err_probe(dev, ret, "failed to find backlight\n");
drm_panel_add(&dimming_panel->base);
dimming_panel->id = bitmap_find_next_zero_area(allocated_dimming_panels,
MAX_DIMMING_PANELS, 0, 1, 0);
dimming_dev = device_create(rockchip_dimming_class, dev, MKDEV(0, 0), spi,
"dimming_%d", dimming_panel->id);
if (IS_ERR(dimming_dev)) {
dev_err(dev, "Failed to create rockchip dimming device\n");
ret = PTR_ERR(dimming_dev);
goto remove_panel;
}
dimming_panel->dimming_dev = dimming_dev;
bitmap_set(allocated_dimming_panels, dimming_panel->id, 1);
dev_set_drvdata(dimming_dev, spi);
ret = sysfs_create_group(&dimming_dev->kobj, &rockchip_dimming_attr_group);
if (ret)
goto destroy_device;
devm_rockchip_panel_notifier_register(dev, &dimming_panel->base,
&dimming_panel->panel_notifier);
dimming_panel->dimming_worker = kthread_create_worker(0, dev_name(dimming_dev));
if (IS_ERR(dimming_panel->dimming_worker)) {
dev_err(dimming_dev, "Failed to create rockchip dimming worker\n");
ret = PTR_ERR(dimming_panel->dimming_worker);
goto remove_group;
}
kthread_init_delayed_work(&dimming_panel->dimming_delayed_work, dimming_delayed_work_func);
dimming_panel->sub_dev.of_node = dev->of_node;
dimming_panel->sub_dev.loader_protect = rockchip_dimming_panel_loader_protect;
rockchip_drm_register_sub_dev(&dimming_panel->sub_dev);
return 0;
remove_group:
sysfs_remove_group(&dimming_dev->kobj, &rockchip_dimming_attr_group);
destroy_device:
bitmap_clear(allocated_dimming_panels, dimming_panel->id, 1);
device_destroy(rockchip_dimming_class, dimming_dev->devt);
remove_panel:
drm_panel_remove(&dimming_panel->base);
return ret;
}
static void rockchip_dimming_panel_remove(struct spi_device *spi)
{
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
struct device *dimming_dev = dimming_panel->dimming_dev;
rockchip_drm_unregister_sub_dev(&dimming_panel->sub_dev);
kthread_destroy_worker(dimming_panel->dimming_worker);
sysfs_remove_group(&dimming_dev->kobj, &rockchip_dimming_attr_group);
bitmap_clear(allocated_dimming_panels, dimming_panel->id, 1);
device_destroy(rockchip_dimming_class, dimming_dev->devt);
drm_panel_remove(&dimming_panel->base);
drm_panel_disable(&dimming_panel->base);
drm_panel_unprepare(&dimming_panel->base);
}
static void rockchip_dimming_panel_shutdown(struct spi_device *spi)
{
struct rockchip_dimming_panel *dimming_panel = dev_get_drvdata(&spi->dev);
drm_panel_disable(&dimming_panel->base);
drm_panel_unprepare(&dimming_panel->base);
}
static const struct spi_device_id rockchip_dimming_panel_ids[] = {
{ .name = "rockchip,dimming-panel" },
{},
};
MODULE_DEVICE_TABLE(spi, rockchip_dimming_panel_ids);
static const struct of_device_id rockchip_dimming_panel_of_match[] = {
{ .compatible = "rockchip,dimming-panel" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, rockchip_dimming_panel_of_match);
static struct spi_driver rockchip_dimming_panel_driver = {
.probe = rockchip_dimming_panel_probe,
.remove = rockchip_dimming_panel_remove,
.shutdown = rockchip_dimming_panel_shutdown,
.id_table = rockchip_dimming_panel_ids,
.driver = {
.name = "rockchip-dimming-panel",
.of_match_table = rockchip_dimming_panel_of_match,
},
};
static int __init rockchip_dimming_panel_init(void)
{
rockchip_dimming_class = class_create(THIS_MODULE, "dimming");
if (IS_ERR(rockchip_dimming_class)) {
pr_err("Failed to create rockchip dimming class\n");
return PTR_ERR(rockchip_dimming_class);
}
return spi_register_driver(&rockchip_dimming_panel_driver);
}
module_init(rockchip_dimming_panel_init);
static void __exit rockchip_dimming_panel_exit(void)
{
spi_unregister_driver(&rockchip_dimming_panel_driver);
class_destroy(rockchip_dimming_class);
}
module_exit(rockchip_dimming_panel_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Damon Ding <damon.ding@rock-chips.com>");
MODULE_DESCRIPTION("rockchip dimming panel");
MODULE_SOFTDEP("pre: rockchipdrm");

View File

@@ -292,10 +292,6 @@ EXPORT_SYMBOL(drm_mode_convert_to_origin_mode);
uint32_t rockchip_drm_get_bpp(const struct drm_format_info *info)
{
/* use whatever a driver has set */
if (info->cpp[0])
return info->cpp[0] * 8;
switch (info->format) {
case DRM_FORMAT_YUV420_8BIT:
return 12;
@@ -304,11 +300,8 @@ uint32_t rockchip_drm_get_bpp(const struct drm_format_info *info)
case DRM_FORMAT_VUY101010:
return 30;
default:
break;
return drm_format_info_bpp(info, 0);
}
/* all attempts failed */
return 0;
}
EXPORT_SYMBOL(rockchip_drm_get_bpp);

View File

@@ -36,7 +36,6 @@
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_vblank.h>
#include <drm/drm_writeback.h>
@@ -4839,7 +4838,7 @@ static void vop_tv_config_update(struct drm_crtc *crtc,
if (vop_data->feature & VOP_FEATURE_OUTPUT_10BIT)
brightness = interpolate(0, -128, 100, 127, s->tv_state->brightness);
else if (VOP_MAJOR(vop->version) == 2 && VOP_MINOR(vop->version) == 6) /* px30 vopb */
else if (vop->version == VOP_VERSION_PX30_BIG || vop->version >= VOP_VERSION_RK3506)
brightness = interpolate(0, -64, 100, 63, s->tv_state->brightness);
else
brightness = interpolate(0, -32, 100, 31, s->tv_state->brightness);
@@ -5743,11 +5742,6 @@ static int vop_create_crtc(struct vop *vop)
VOP_ATTACH_MODE_CONFIG_PROP(tv_bottom_margin_property, 100);
#undef VOP_ATTACH_MODE_CONFIG_PROP
vop_crtc_create_feature_property(vop, crtc);
ret = drm_self_refresh_helper_init(crtc);
if (ret)
DRM_DEV_DEBUG_KMS(vop->dev,
"Failed to init %s with SR helpers %d, ignoring\n",
crtc->name, ret);
if (vop->lut_regs) {
u16 *r_base, *g_base, *b_base;
@@ -5755,8 +5749,10 @@ static int vop_create_crtc(struct vop *vop)
vop->lut = devm_kmalloc_array(dev, lut_len, sizeof(*vop->lut),
GFP_KERNEL);
if (!vop->lut)
if (!vop->lut) {
ret = -ENOMEM;
goto err_unregister_crtc_funcs;
}
if (vop_of_init_display_lut(vop)) {
for (i = 0; i < lut_len; i++) {
@@ -5799,8 +5795,6 @@ static void vop_destroy_crtc(struct vop *vop)
struct drm_device *drm_dev = vop->drm_dev;
struct drm_plane *plane, *tmp;
drm_self_refresh_helper_cleanup(crtc);
of_node_put(crtc->port);
/*

View File

@@ -14,7 +14,6 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <drm/drm_writeback.h>
#ifdef CONFIG_DRM_ANALOGIX_DP
@@ -1111,6 +1110,8 @@ static inline void rk3588_vop2_dsc_cfg_done(struct drm_crtc *crtc);
static inline void vop2_cfg_done(struct drm_crtc *crtc);
static void vop2_wait_for_fs_by_done_bit_status(struct vop2_video_port *vp);
static int vop2_clk_reset(struct reset_control *rstc);
static inline bool vop2_cluster_sub_window(struct vop2_win *win);
static inline bool vop2_multi_area_sub_window(struct vop2_win *win);
static void vop2_wait_for_scan_timing_max_to_assigned_line(struct vop2_video_port *vp,
u32 current_line,
u32 wait_line);
@@ -2284,14 +2285,17 @@ static void vop2_win_disable(struct vop2_win *win, bool skip_splice_win)
}
}
vp_id = ffs(win->vp_mask) - 1;
if (vp_id >= ROCKCHIP_MAX_CRTC) {
DRM_ERROR("Unsupported vp_id: %d\n", vp_id);
return;
if (!vop2_cluster_sub_window(win) && !vop2_multi_area_sub_window(win)) {
vp_id = ffs(win->vp_mask) - 1;
if (vp_id >= ROCKCHIP_MAX_CRTC) {
DRM_ERROR("%s unsupported vp_id: %d, win->vp_mask:0x%x\n",
win->name, vp_id, win->vp_mask);
return;
}
vp = &vop2->vps[vp_id];
if (vp->reserved_plane_phy_id != ROCKCHIP_VOP2_PHY_ID_INVALID)
vp->win_cfg_done_bits |= BIT(win->reg_done_bit);
}
vp = &vop2->vps[vp_id];
if (vp->reserved_plane_phy_id != ROCKCHIP_VOP2_PHY_ID_INVALID)
vp->win_cfg_done_bits |= BIT(win->reg_done_bit);
}
if (win->left_win && win->splice_mode_right) {
@@ -2428,8 +2432,6 @@ static enum vop2_afbc_format vop2_convert_afbc_format(uint32_t format)
DRM_WARN_ONCE("unsupported AFBC format %p4cc\n", &format);
return VOP2_AFBC_FMT_INVALID;
}
return VOP2_AFBC_FMT_INVALID;
}
static enum vop2_tiled_format vop2_convert_tiled_format(uint32_t format)
@@ -2454,8 +2456,6 @@ static enum vop2_tiled_format vop2_convert_tiled_format(uint32_t format)
DRM_WARN_ONCE("unsupported tiled format %p4cc\n", &format);
return VOP2_TILED_FMT_INVALID;
}
return VOP2_TILED_FMT_INVALID;
}
static enum vop3_tiled_format vop3_convert_tiled_format(uint32_t format, uint32_t tile_mode)
@@ -2486,8 +2486,6 @@ static enum vop3_tiled_format vop3_convert_tiled_format(uint32_t format, uint32_
DRM_WARN_ONCE("unsupported tiled format %p4cc\n", &format);
return VOP3_TILED_FMT_INVALID;
}
return VOP3_TILED_FMT_INVALID;
}
static enum vop2_wb_format vop2_convert_wb_format(uint32_t format)
@@ -5354,12 +5352,6 @@ static void vop2_disable(struct drm_crtc *crtc)
/* Disable axi irq when all vp is disabled */
vop2_axi_disable_irqs(vop2);
/*
* Reset AXI to get a clean state, which is conducive to recovering
* from exceptions when enable at next time(such as iommu page fault)
*/
vop2_clk_reset(vop2->axi_rst);
if (vop2->is_iommu_enabled) {
/*
* vop2 standby complete, so iommu detach is safe.
@@ -5382,6 +5374,12 @@ static void vop2_disable(struct drm_crtc *crtc)
if (vop2->version == VOP_VERSION_RK3588 || vop2->version == VOP_VERSION_RK3576)
vop2_power_off_all_pd(vop2);
/*
* Reset AXI to get a clean state, which is conducive to recovering
* from exceptions when enable at next time(such as iommu page fault)
*/
vop2_clk_reset(vop2->axi_rst);
vop2->is_enabled = false;
pm_runtime_put_sync(vop2->dev);
@@ -7167,7 +7165,8 @@ static void vop2_win_atomic_update(struct vop2_win *win, struct drm_rect *src, s
VOP_CLUSTER_SET(vop2, win, frm_reset_en, 1);
VOP_CLUSTER_SET(vop2, win, dma_stride_4k_disable, 1);
}
vp->win_cfg_done_bits |= BIT(win->reg_done_bit);
if (!vop2_cluster_sub_window(win) && !vop2_multi_area_sub_window(win))
vp->win_cfg_done_bits |= BIT(win->reg_done_bit);
spin_unlock(&vop2->reg_lock);
}
@@ -15373,12 +15372,6 @@ static int vop2_create_crtc(struct vop2 *vop2, uint8_t enabled_vp_mask)
vop2_crtc_create_feature_property(vop2, crtc);
vop2_crtc_create_vrr_property(vop2, crtc);
ret = drm_self_refresh_helper_init(crtc);
if (ret)
DRM_DEV_DEBUG_KMS(vop2->dev,
"Failed to init %s with SR helpers %d, ignoring\n",
crtc->name, ret);
if (vp_data->feature & (VOP_FEATURE_VIVID_HDR | VOP_FEATURE_DOVI))
vop2_crtc_create_hdr_property(vop2, crtc);
if (vp_data->feature & VOP_FEATURE_POST_ACM)
@@ -15466,7 +15459,6 @@ static void vop2_destroy_crtc(struct drm_crtc *crtc)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
drm_self_refresh_helper_cleanup(crtc);
if (vp->hdr_lut_gem_obj)
rockchip_gem_free_object(&vp->hdr_lut_gem_obj->base);

View File

@@ -22,6 +22,7 @@
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_self_refresh_helper.h>
#include <uapi/linux/videodev2.h>
@@ -47,6 +48,8 @@
#define RV1126B_GRF_VOP_LCDC_CON 0x30b9c
#define RV1126B_VOP_MCU_SEL(v) HIWORD_UPDATE(v, 15, 15)
#define RV1126B_VOP_DCLK_DLL_NUM(v) HIWORD_UPDATE(v, 8, 14)
#define RV1126B_VOP_DCLK_DLL_SEL(v) HIWORD_UPDATE(v, 1, 1)
#define RK3288_GRF_SOC_CON6 0x025c
#define RK3288_LVDS_LCDC_SEL(x) HIWORD_UPDATE(x, 3, 3)
@@ -912,6 +915,38 @@ static struct backlight_device *rockchip_mcu_panel_find_backlight(struct rockchi
return bd;
}
static void rockchip_rgb_drm_self_refresh_helper_init(struct rockchip_rgb *rgb)
{
struct drm_encoder *encoder = &rgb->encoder;
struct drm_crtc *crtc;
int ret;
if (rgb->np_mcu_panel && rgb->support_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc)) {
ret = drm_self_refresh_helper_init(crtc);
if (ret)
dev_warn(rgb->dev,
"Failed to init self refresh helper for crtc-%d\n",
drm_crtc_index(crtc));
}
}
}
}
static void rockchip_rgb_drm_self_refresh_helper_cleanup(struct rockchip_rgb *rgb)
{
struct drm_encoder *encoder = &rgb->encoder;
struct drm_crtc *crtc;
if (rgb->np_mcu_panel && rgb->support_psr) {
drm_for_each_crtc(crtc, encoder->dev) {
if (drm_encoder_crtc_ok(encoder, crtc))
drm_self_refresh_helper_cleanup(crtc);
}
}
}
static int rockchip_rgb_bind(struct device *dev, struct device *master,
void *data)
{
@@ -1017,6 +1052,8 @@ static int rockchip_rgb_bind(struct device *dev, struct device *master,
rockchip_drm_register_sub_dev(&rgb->sub_dev);
}
rockchip_rgb_drm_self_refresh_helper_init(rgb);
return 0;
err_free_connector:
@@ -1031,6 +1068,8 @@ static void rockchip_rgb_unbind(struct device *dev, struct device *master,
{
struct rockchip_rgb *rgb = dev_get_drvdata(dev);
rockchip_rgb_drm_self_refresh_helper_cleanup(rgb);
if (rgb->sub_dev.connector)
rockchip_drm_unregister_sub_dev(&rgb->sub_dev);
if (rgb->panel)
@@ -1252,6 +1291,14 @@ static const struct rockchip_rgb_data rv1126_rgb = {
static void rv1126b_rgb_enable(struct rockchip_rgb *rgb)
{
struct drm_crtc *crtc = rgb->encoder.crtc;
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
if (s->output_if == VOP_OUTPUT_IF_BT1120 || s->output_if == VOP_OUTPUT_IF_BT656) {
regmap_write(rgb->grf, RV1126B_GRF_VOP_LCDC_CON, RV1126B_VOP_DCLK_DLL_SEL(1));
regmap_write(rgb->grf, RV1126B_GRF_VOP_LCDC_CON, RV1126B_VOP_DCLK_DLL_NUM(0x15));
}
regmap_write(rgb->grf, RV1126B_GRF_VOP_LCDC_CON,
RV1126B_VOP_MCU_SEL(rgb->data_sync_bypass));
}

View File

@@ -2001,7 +2001,7 @@ static const struct vop_ctrl rv1126b_ctrl_data = {
.bcsh_r2y_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 7),
.bcsh_color_bar = VOP_REG(RK3366_LIT_BCSH_COL_BAR, 0xffffff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0xff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0x7f, 0),
.bcsh_contrast = VOP_REG(RK3366_LIT_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3366_LIT_BCSH_BCS, 0x3ff, 20),
.bcsh_sin_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 0),
@@ -2219,7 +2219,7 @@ static const struct vop_ctrl rk3506_ctrl_data = {
.bcsh_r2y_en = VOP_REG(RK3366_LIT_BCSH_CTRL, 0x1, 7),
.bcsh_color_bar = VOP_REG(RK3366_LIT_BCSH_COL_BAR, 0xffffff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0xff, 0),
.bcsh_brightness = VOP_REG(RK3366_LIT_BCSH_BCS, 0x7f, 0),
.bcsh_contrast = VOP_REG(RK3366_LIT_BCSH_BCS, 0x1ff, 8),
.bcsh_sat_con = VOP_REG(RK3366_LIT_BCSH_BCS, 0x3ff, 20),
.bcsh_sin_hue = VOP_REG(RK3366_LIT_BCSH_H, 0x1ff, 0),

View File

@@ -181,6 +181,10 @@ struct os12d40 {
const char *module_name;
const char *len_name;
struct rkmodule_awb_cfg awb_cfg;
bool has_init_wbgain;
bool has_init_blc;
struct rkmodule_wb_gain_group init_wbgain;
struct rkmodule_blc_group init_blc;
};
#define to_os12d40(sd) container_of(sd, struct os12d40, subdev)
@@ -2271,6 +2275,87 @@ static void os12d40_set_awb_cfg(struct os12d40 *os12d40,
mutex_unlock(&os12d40->mutex);
}
static int os12d40_set_wb_gain(struct os12d40 *os12d40,
struct rkmodule_wb_gain_group *wb_gain_group)
{
struct rkmodule_wb_gain wb_gain;
u16 reg_bgain = 0, reg_gbgain = 0, reg_grgain = 0, reg_rgain = 0;
int ret = 0;
#ifdef DEBUG
u32 bgain = 0, gbgain = 0, grgain = 0, rgain = 0;
#endif
if (!os12d40->has_init_wbgain && !os12d40->streaming) {
os12d40->init_wbgain = *wb_gain_group;
os12d40->has_init_wbgain = true;
dev_dbg(&os12d40->client->dev, "os12d40 don't stream, record wbgain!\n");
return ret;
}
reg_bgain = 0x7000;
reg_gbgain = 0x7002;
reg_grgain = 0x7004;
reg_rgain = 0x7006;
wb_gain = wb_gain_group->wb_gain[0];
ret = os12d40_write_reg(os12d40->client, reg_bgain,
OS12D40_REG_VALUE_16BIT, wb_gain.b_gain & 0xffff);
ret |= os12d40_write_reg(os12d40->client, reg_grgain,
OS12D40_REG_VALUE_16BIT, wb_gain.gr_gain & 0xffff);
ret |= os12d40_write_reg(os12d40->client, reg_gbgain,
OS12D40_REG_VALUE_16BIT, wb_gain.gb_gain & 0xffff);
ret |= os12d40_write_reg(os12d40->client, reg_rgain,
OS12D40_REG_VALUE_16BIT, wb_gain.r_gain & 0xffff);
dev_info(&os12d40->client->dev,
"write wb gain, type:%d, b:0x%x, gb:0x%x, gr:0x%x, r:0x%x\n",
wb_gain_group->wb_gain_type[0],
wb_gain.b_gain, wb_gain.gb_gain,
wb_gain.gr_gain, wb_gain.r_gain);
#ifdef DEBUG
ret |= os12d40_read_reg(os12d40->client, reg_bgain,
OS12D40_REG_VALUE_16BIT, &bgain);
ret |= os12d40_read_reg(os12d40->client, reg_gbgain,
OS12D40_REG_VALUE_16BIT, &gbgain);
ret |= os12d40_read_reg(os12d40->client, reg_grgain,
OS12D40_REG_VALUE_16BIT, &grgain);
ret |= os12d40_read_reg(os12d40->client, reg_rgain,
OS12D40_REG_VALUE_16BIT, &rgain);
dev_info(&os12d40->client->dev,
"read wb gain, type %d, b:0x%x, gb:0x%x, gr:0x%x, r:0x%x\n",
wb_gain_group->wb_gain_type[0], bgain, gbgain, grgain, rgain);
#endif
return ret;
}
static int os12d40_set_blc(struct os12d40 *os12d40,
struct rkmodule_blc_group *blc_group)
{
u32 reg_blc = 0;
u32 blc_val = 0;
int ret = 0;
if (!os12d40->has_init_blc && !os12d40->streaming) {
os12d40->init_blc = *blc_group;
os12d40->has_init_blc = true;
dev_dbg(&os12d40->client->dev, "os12d40 don't stream, record blc!\n");
return ret;
}
reg_blc = 0x4019;
blc_val = blc_group->blc[0];
ret = os12d40_write_reg(os12d40->client, reg_blc,
OS12D40_REG_VALUE_16BIT, blc_val & 0x3ff);
dev_info(&os12d40->client->dev,
"write blc, type:%d, blc_val:0x%x\n",
blc_group->blc_type[0],
blc_val);
#ifdef DEBUG
ret |= os12d40_read_reg(os12d40->client, reg_blc,
OS12D40_REG_VALUE_16BIT, &blc_val);
dev_info(&os12d40->client->dev,
"read blc, type %d, blc_val:0x%x\n",
blc_group->blc_type[0], blc_val);
#endif
return ret;
}
static long os12d40_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
struct os12d40 *os12d40 = to_os12d40(sd);
@@ -2278,6 +2363,10 @@ static long os12d40_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
long ret = 0;
u32 stream = 0;
u32 *bayer_mode;
struct rkmodule_wb_gain_info *wb_gain_info;
struct rkmodule_blc_info *blc_info;
struct rkmodule_wb_gain_group *wb_gain_group;
struct rkmodule_blc_group *blc_group;
switch (cmd) {
case RKMODULE_GET_MODULE_INFO:
@@ -2318,6 +2407,23 @@ static long os12d40_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
*bayer_mode = RKMODULE_NORMAL_BAYER;
#endif
break;
case RKMODULE_GET_WB_GAIN_INFO:
wb_gain_info = (struct rkmodule_wb_gain_info *)arg;
wb_gain_info->coarse_bit = 5;
wb_gain_info->fine_bit = 10;
break;
case RKMODULE_GET_BLC_INFO:
blc_info = (struct rkmodule_blc_info *)arg;
blc_info->bit_width = 10;
break;
case RKMODULE_SET_WB_GAIN:
wb_gain_group = (struct rkmodule_wb_gain_group *)arg;
ret = os12d40_set_wb_gain(os12d40, wb_gain_group);
break;
case RKMODULE_SET_BLC:
blc_group = (struct rkmodule_blc_group *)arg;
ret = os12d40_set_blc(os12d40, blc_group);
break;
default:
ret = -ENOIOCTLCMD;
break;
@@ -2337,6 +2443,10 @@ static long os12d40_compat_ioctl32(struct v4l2_subdev *sd,
long ret;
u32 stream = 0;
u32 bayer_mode = 0;
struct rkmodule_wb_gain_info *wb_gain_info;
struct rkmodule_blc_info *blc_info;
struct rkmodule_wb_gain_group *wb_gain_group;
struct rkmodule_blc_group *blc_group;
switch (cmd) {
case RKMODULE_GET_MODULE_INFO:
@@ -2413,6 +2523,68 @@ static long os12d40_compat_ioctl32(struct v4l2_subdev *sd,
return -EFAULT;
}
break;
case RKMODULE_GET_WB_GAIN_INFO:
wb_gain_info = kzalloc(sizeof(*wb_gain_info), GFP_KERNEL);
if (!wb_gain_info) {
ret = -ENOMEM;
return ret;
}
ret = os12d40_ioctl(sd, cmd, wb_gain_info);
if (!ret) {
if (copy_to_user(up, wb_gain_info, sizeof(*wb_gain_info))) {
kfree(wb_gain_info);
return -EFAULT;
}
}
kfree(wb_gain_info);
break;
case RKMODULE_GET_BLC_INFO:
blc_info = kzalloc(sizeof(*blc_info), GFP_KERNEL);
if (!blc_info) {
ret = -ENOMEM;
return ret;
}
ret = os12d40_ioctl(sd, cmd, blc_info);
if (!ret) {
if (copy_to_user(up, blc_info, sizeof(*blc_info))) {
kfree(blc_info);
return -EFAULT;
}
}
kfree(blc_info);
break;
case RKMODULE_SET_WB_GAIN:
wb_gain_group = kzalloc(sizeof(*wb_gain_group), GFP_KERNEL);
if (!wb_gain_group) {
ret = -ENOMEM;
return ret;
}
ret = os12d40_ioctl(sd, cmd, wb_gain_group);
if (!ret) {
ret = copy_to_user(up, wb_gain_group, sizeof(*wb_gain_group));
if (ret)
return -EFAULT;
}
kfree(wb_gain_group);
break;
case RKMODULE_SET_BLC:
blc_group = kzalloc(sizeof(*blc_group), GFP_KERNEL);
if (!blc_group) {
ret = -ENOMEM;
return ret;
}
ret = os12d40_ioctl(sd, cmd, blc_group);
if (!ret) {
ret = copy_to_user(up, blc_group, sizeof(*blc_group));
if (ret)
return -EFAULT;
}
kfree(blc_group);
break;
default:
ret = -ENOIOCTLCMD;
break;
@@ -2452,6 +2624,26 @@ static int __os12d40_start_stream(struct os12d40 *os12d40)
if (ret)
return ret;
if (os12d40->has_init_wbgain) {
ret = os12d40_ioctl(&os12d40->subdev,
RKMODULE_SET_WB_GAIN,
&os12d40->init_wbgain);
if (ret) {
dev_err(&os12d40->client->dev,
"init wbgain fail\n");
return ret;
}
}
if (os12d40->has_init_blc) {
ret = os12d40_ioctl(&os12d40->subdev,
RKMODULE_SET_BLC,
&os12d40->init_blc);
if (ret) {
dev_err(&os12d40->client->dev,
"init blc fail\n");
return ret;
}
}
ret = os12d40_write_reg(os12d40->client, OS12D40_REG_CTRL_MODE,
OS12D40_REG_VALUE_08BIT, OS12D40_MODE_STREAMING);
return ret;
@@ -2459,6 +2651,8 @@ static int __os12d40_start_stream(struct os12d40 *os12d40)
static int __os12d40_stop_stream(struct os12d40 *os12d40)
{
os12d40->has_init_wbgain = false;
os12d40->has_init_blc = false;
return os12d40_write_reg(os12d40->client, OS12D40_REG_CTRL_MODE,
OS12D40_REG_VALUE_08BIT, OS12D40_MODE_SW_STANDBY);
}
@@ -3001,6 +3195,8 @@ static int os12d40_initialize_controls(struct os12d40 *os12d40)
}
os12d40->subdev.ctrl_handler = handler;
os12d40->has_init_wbgain = false;
os12d40->has_init_blc = false;
return 0;

File diff suppressed because it is too large Load Diff

View File

@@ -335,6 +335,8 @@ static void rk628_bt1120_hdmirx_reset(struct v4l2_subdev *sd)
bt1120->hdcp.hdcp_start = false;
enable_irq(bt1120->plugin_irq);
enable_irq(bt1120->hdmirx_irq);
if (bt1120->cec && bt1120->cec->adap)
rk628_hdmirx_cec_state_reconfiguration(bt1120->rk628, bt1120->cec);
}
static void rk628_hdmirx_plugout(struct v4l2_subdev *sd)
@@ -438,8 +440,6 @@ static void rk628_bt1120_delayed_work_enable_hotplug(struct work_struct *work)
rk628_hdmirx_controller_setup(bt1120->rk628);
rk628_hdmirx_hpd_ctrl(sd, true);
rk628_hdmirx_config_all(sd);
if (bt1120->cec && bt1120->cec->adap)
rk628_hdmirx_cec_state_reconfiguration(bt1120->rk628, bt1120->cec);
rk628_bt1120_enable_interrupts(sd, true);
} else {
bt1120->nosignal = true;

View File

@@ -498,6 +498,8 @@ static void rk628_csi_hdmirx_reset(struct v4l2_subdev *sd)
csi->hdcp.hdcp_start = false;
enable_irq(csi->plugin_irq);
enable_irq(csi->hdmirx_irq);
if (csi->cec && csi->cec->adap)
rk628_hdmirx_cec_state_reconfiguration(csi->rk628, csi->cec);
}
static void rk628_hdmirx_plugout(struct v4l2_subdev *sd)
@@ -574,8 +576,6 @@ static void rk628_csi_delayed_work_enable_hotplug(struct work_struct *work)
rk628_hdmirx_controller_setup(csi->rk628);
rk628_hdmirx_hpd_ctrl(sd, true);
rk628_hdmirx_config_all(sd);
if (csi->cec && csi->cec->adap)
rk628_hdmirx_cec_state_reconfiguration(csi->rk628, csi->cec);
rk628_csi_enable_interrupts(sd, true);
} else {
extcon_set_state_sync(csi->extcon, EXTCON_JACK_VIDEO_IN, false);

View File

@@ -174,8 +174,8 @@ static void rkaiisp_dumpreg(struct rkaiisp_device *aidev, u32 start, u32 end)
static void rkaiisp_dump_list_reg(struct rkaiisp_device *aidev)
{
dev_info(aidev->dev, "frame_id: %d, run_idx: %d\n",
aidev->frame_id, aidev->run_idx);
dev_info(aidev->dev, "frame_id: %d, run_idx: %d, parthdl %d\n",
aidev->frame_id, aidev->run_idx, aidev->parthdl_idx);
rkaiisp_dumpreg(aidev, AIISP_CORE_CTRL, AIISP_CORE_NOISE_LMT);
rkaiisp_dumpreg(aidev, AIISP_CORE_COMP0, AIISP_CORE_DECOMP16);
@@ -350,6 +350,24 @@ static void rkaiisp_free_buffer(struct rkaiisp_device *aidev,
}
}
static void __maybe_unused rkaiisp_prepare_buffer(struct rkaiisp_device *aidev,
struct rkaiisp_dummy_buffer *buf)
{
const struct vb2_mem_ops *g_ops = aidev->hw_dev->mem_ops;
if (buf && buf->mem_priv)
g_ops->prepare(buf->mem_priv);
}
static void __maybe_unused rkaiisp_finish_buffer(struct rkaiisp_device *aidev,
struct rkaiisp_dummy_buffer *buf)
{
const struct vb2_mem_ops *g_ops = aidev->hw_dev->mem_ops;
if (buf && buf->mem_priv)
g_ops->finish(buf->mem_priv);
}
static void rkaiisp_detach_dmabuf(struct rkaiisp_device *aidev,
struct rkaiisp_dummy_buffer *buffer)
{
@@ -637,6 +655,9 @@ static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf
if (aidev->exealgo == AIYNR) {
stride = ((ispbuf->iir_width + 3) / 4 * 8 * 11 + 7) >> 3;
size = stride * (ispbuf->iir_height + 3) / 4;
} else if (aidev->mem_mode == COMBO_MEMODE) {
stride = ((ispbuf->iir_width + 7) / 8 * 15 * 11 + 7) >> 3;
size = stride * (ispbuf->iir_height + 7) / 8;
} else {
stride = ((ispbuf->iir_width + 1) / 2 * 15 * 11 + 7) >> 3;
size = stride * (ispbuf->iir_height + 1) / 2;
@@ -651,6 +672,7 @@ static int rkaiisp_init_pool(struct rkaiisp_device *aidev, struct rkaiisp_ispbuf
aidev->ispbuf = *ispbuf;
aidev->outbuf_idx = 0;
aidev->parthdl_num = 1;
aidev->init_buf = true;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev, "init buf poll\n");
@@ -670,7 +692,6 @@ static int rkaiisp_free_airms_pool(struct rkaiisp_device *aidev)
for (i = 0; i < aidev->rmsbuf.outbuf_num; i++)
rkaiisp_free_buffer(aidev, &aidev->rms_outbuf[i]);
rkaiisp_free_buffer(aidev, &aidev->sigma_buf);
rkaiisp_free_buffer(aidev, &aidev->narmap_buf);
aidev->init_buf = false;
@@ -682,9 +703,12 @@ static int rkaiisp_free_airms_pool(struct rkaiisp_device *aidev)
static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_rmsbuf_info *rmsbuf)
{
int i, ret = 0;
u32 bin_width, bin_height;
u32 size;
size = rmsbuf->image_width * rmsbuf->image_height * 2;
bin_width = CEIL_BY(CEIL_DOWN(rmsbuf->image_width, 2), 2);
bin_height = CEIL_BY(CEIL_DOWN(rmsbuf->image_height, 2), 2);
size = rmsbuf->image_width * rmsbuf->image_height * 2 + bin_width * bin_height;
rmsbuf->inbuf_num = RKAIISP_MIN(rmsbuf->inbuf_num, RKAIISP_AIRMS_BUF_MAXCNT);
for (i = 0; i < rmsbuf->inbuf_num; i++) {
aidev->rms_inbuf[i].size = size;
@@ -700,6 +724,25 @@ static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_
rmsbuf->inbuf_fd[i] = aidev->rms_inbuf[i].dma_fd;
}
aidev->rmsbuf = *rmsbuf;
aidev->part_rmsbuf = aidev->rmsbuf;
if (rmsbuf->image_width > RKAIISP_AIRMS_MAX_WIDTH) {
int proc_width;
aidev->is_parthdl = true;
aidev->parthdl_num = 2;
proc_width = aidev->part_rmsbuf.image_width / 2 + RKAIISP_AIRMS_EXTEND_PIXEL;
aidev->part_rmsbuf.image_width = CEIL_BY(proc_width, 16);
aidev->part_rmsbuf.sigma_width = aidev->part_rmsbuf.image_width / 2;
aidev->part_rmsbuf.narmap_width = (aidev->part_rmsbuf.image_width + 7) / 8 * 2;
aidev->parthdl_image_oft = aidev->rmsbuf.image_width - aidev->part_rmsbuf.image_width;
size = (CEIL_BY(rmsbuf->image_width, 2) + 2 * RKAIISP_AIRMS_EXTEND_PIXEL) * rmsbuf->image_height * 2;
} else {
aidev->is_parthdl = false;
aidev->parthdl_num = 1;
size = rmsbuf->image_width * rmsbuf->image_height * 2;
}
rmsbuf->outbuf_num = RKAIISP_MIN(rmsbuf->outbuf_num, RKAIISP_AIRMS_BUF_MAXCNT);
for (i = 0; i < rmsbuf->outbuf_num; i++) {
aidev->rms_outbuf[i].size = size;
@@ -715,18 +758,12 @@ static int rkaiisp_init_airms_pool(struct rkaiisp_device *aidev, struct rkaiisp_
rmsbuf->outbuf_fd[i] = aidev->rms_outbuf[i].dma_fd;
}
aidev->sigma_buf.size = rmsbuf->sigma_width * rmsbuf->sigma_height;
aidev->sigma_buf.is_need_vaddr = false;
aidev->sigma_buf.is_need_dbuf = false;
aidev->sigma_buf.is_need_dmafd = false;
rkaiisp_allow_buffer(aidev, &aidev->sigma_buf);
aidev->narmap_buf.size = rmsbuf->narmap_width * rmsbuf->narmap_height;
aidev->narmap_buf.size = aidev->rmsbuf.narmap_width * aidev->rmsbuf.narmap_height;
aidev->narmap_buf.is_need_vaddr = false;
aidev->narmap_buf.is_need_dbuf = false;
aidev->narmap_buf.is_need_dmafd = false;
rkaiisp_allow_buffer(aidev, &aidev->narmap_buf);
aidev->rmsbuf = *rmsbuf;
aidev->init_buf = true;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev, "init buf poll\n");
@@ -880,6 +917,13 @@ static void rkaiisp_gen_slice_param(struct rkaiisp_device *aidev,
}
}
if (slice_idx > 8) {
aidev->is_state_err = true;
v4l2_err(&aidev->v4l2_dev,
"slice num %d is too big, input width %d\n", slice_idx, width);
return;
}
if (slice_idx >= 1)
slice_num = slice_idx - 1;
value = slice_mode[0] |
@@ -990,6 +1034,9 @@ static int rkaiisp_determine_size(struct rkaiisp_device *aidev,
if (n == 3 && model_cfg->sw_mi_chn3_sel == 0)
bits = 8;
if (aidev->chn_size[n].stride != 0 && aidev->exealgo == AIRMS)
cols = aidev->chn_size[n].stride;
sw_mi_chn_stride[n] = CEIL_BY(cols * chns * bits, 16 * 8) / 32;
}
@@ -1130,6 +1177,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
{
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
struct rkaiisp_rmsbuf_info *rmsbuf = &aidev->rmsbuf;
struct rkaiisp_rmsbuf_info *part_rmsbuf = &aidev->part_rmsbuf;
struct rkaiisp_dummy_buffer *vpsl_buf;
dma_addr_t dma_addr;
u32 width, height, stride;
@@ -1239,20 +1287,29 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
dma_addr = aidev->lastout_buf[aidev->outbuf_idx]->dma_addr;
break;
case VICAP_BAYER_RAW:
width = rmsbuf->image_width;
height = rmsbuf->image_height;
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
break;
case ALLZERO_SIGMA:
width = rmsbuf->sigma_width;
height = rmsbuf->sigma_height;
dma_addr = aidev->sigma_buf.dma_addr;
sig_width = width;
if (aidev->is_parthdl) {
width = part_rmsbuf->image_width;
height = part_rmsbuf->image_height;
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
if (aidev->parthdl_idx == 1)
dma_addr += aidev->parthdl_image_oft * 2;
stride = rmsbuf->image_width;
} else {
width = rmsbuf->image_width;
height = rmsbuf->image_height;
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr;
}
break;
case ALLZERO_NARMAP:
width = rmsbuf->narmap_width;
height = rmsbuf->narmap_height;
if (aidev->is_parthdl) {
width = part_rmsbuf->narmap_width;
height = part_rmsbuf->narmap_height;
} else {
width = rmsbuf->narmap_width;
height = rmsbuf->narmap_height;
}
dma_addr = aidev->narmap_buf.dma_addr;
break;
case ISP_FINAL_Y:
@@ -1261,6 +1318,28 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
buffer_index = aidev->curr_idxbuf.aibnr_st.y_src_index;
dma_addr = aidev->ynrinbuf[buffer_index].dma_addr;
break;
case VICAP_BAYER_RAW_DOWN:
if (aidev->is_parthdl) {
width = rmsbuf->image_width;
height = rmsbuf->image_height;
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr + width * height * 2;
if (aidev->parthdl_idx == 1)
dma_addr += aidev->parthdl_image_oft / 2;
width = CEIL_BY(CEIL_DOWN(part_rmsbuf->image_width, 2), 2);
height = CEIL_BY(CEIL_DOWN(part_rmsbuf->image_height, 2), 2);
sig_width = width;
stride = CEIL_BY(CEIL_DOWN(rmsbuf->image_width, 2), 2);
} else {
width = rmsbuf->image_width;
height = rmsbuf->image_height;
buffer_index = aidev->curr_idxbuf.airms_st.inbuf_idx;
dma_addr = aidev->rms_inbuf[buffer_index].dma_addr + width * height * 2;
width = CEIL_BY(CEIL_DOWN(rmsbuf->image_width, 2), 2);
height = CEIL_BY(CEIL_DOWN(rmsbuf->image_height, 2), 2);
sig_width = width;
}
break;
default:
width = 0;
height = 0;
@@ -1271,7 +1350,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
if (width > 0) {
aidev->chn_size[i].width = width;
aidev->chn_size[i].height = height;
aidev->chn_size[i].stride = stride;
aidev->chn_size[i].stride = stride > 0 ? stride : width;
rkaiisp_write(aidev, AIISP_MI_RD_CH0_BASE + 0x100 * i, dma_addr, false);
rkaiisp_write(aidev, AIISP_MI_RD_CH0_HEIGHT + 0x100 * i, height, false);
@@ -1289,6 +1368,7 @@ static u32 rkaiisp_config_rdchannel(struct rkaiisp_device *aidev,
static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
{
struct rkaiisp_ispbuf_info *ispbuf = &aidev->ispbuf;
struct rkaiisp_rmsbuf_info *rmsbuf = &aidev->rmsbuf;
struct rkaiisp_params *cur_params;
struct rkaiisp_model_cfg *model_cfg;
int lastlv, lv_mode, out_chns, i;
@@ -1310,6 +1390,7 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
"run frame id: %d, run_idx: %d, model_mode %d\n",
sequence, run_idx, aidev->model_mode);
aidev->is_state_err = false;
cur_params = (struct rkaiisp_params *)aidev->cur_params->vaddr[0];
model_cfg = &cur_params->model_cfg[run_idx];
@@ -1351,10 +1432,17 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
dma_addr = aidev->rms_outbuf[aidev->curr_idxbuf.airms_st.outbuf_idx].dma_addr;
if (aidev->parthdl_idx == 1)
dma_addr += 2 * (CEIL_BY(rmsbuf->image_width, 2) / 2 + RKAIISP_AIRMS_EXTEND_PIXEL);
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_BASE, dma_addr, false);
rkaiisp_gen_slice_param(aidev, model_cfg, sig_width);
rkaiisp_determine_size(aidev, model_cfg);
iir_stride = CEIL_BY(rmsbuf->image_width, 2);
if (aidev->is_parthdl)
iir_stride += 2 * RKAIISP_AIRMS_EXTEND_PIXEL;
rkaiisp_write(aidev, AIISP_MI_CHN0_WR_STRIDE, iir_stride / 2, false);
} else if (aidev->model_mode == SINGLEX2_MODE) {
if (run_idx == 0) {
sig_width = rkaiisp_config_rdchannel(aidev, model_cfg, run_idx);
@@ -1462,7 +1550,8 @@ static void rkaiisp_run_cfg(struct rkaiisp_device *aidev, u32 run_idx)
rkaiisp_write(aidev, AIISP_CORE_LEVEL_CTRL0 + i * 4, val, false);
}
if ((out_chns == 4 && model_cfg->sw_out_d2s_en == 0))
if (out_chns == 4 &&
model_cfg->sw_out_d2s_en == (model_cfg->sw_out_mode == AIISP_OUT_MODE_BYPASS))
sw_lastlv_bypass = 1;
if (model_cfg->sw_aiisp_mode == 0 && model_cfg->sw_out_mode == AIISP_OUT_MODE_DIFF_MERGE)
sw_m0_diff_merge = 1;
@@ -1509,16 +1598,25 @@ static void rkaiisp_run_start(struct rkaiisp_device *aidev)
{
struct rkaiisp_hw_dev *hw_dev = aidev->hw_dev;
if (aidev->is_state_err) {
v4l2_err(&aidev->v4l2_dev,
"aiisp status is error!\n");
rkaiisp_dump_list_reg(aidev);
return;
}
rkaiisp_write(aidev, AIISP_MI_IMSC, AIISP_MI_ISR_ALL, false);
rkaiisp_write(aidev, AIISP_MI_WR_INIT, AIISP_MI_CHN0SELF_FORCE_UPD, false);
if ((aidev->run_idx == 0) && (rkaiisp_showreg != 0))
if ((aidev->run_idx == 0) && (aidev->parthdl_idx == 0) && (rkaiisp_showreg != 0))
aidev->showreg = true;
if (aidev->showreg)
rkaiisp_dump_list_reg(aidev);
if ((aidev->run_idx == aidev->model_runcnt - 1) && aidev->showreg) {
if ((aidev->run_idx + 1 == aidev->model_runcnt) &&
(aidev->parthdl_idx + 1 == aidev->parthdl_num) &&
aidev->showreg) {
aidev->showreg = false;
rkaiisp_showreg = 0;
}
@@ -1593,6 +1691,7 @@ void rkaiisp_trigger(struct rkaiisp_device *aidev)
if (!rkaiisp_update_buf(aidev)) {
aidev->run_idx = 0;
aidev->parthdl_idx = 0;
aidev->frame_id = sequence;
aidev->pre_frm_st = aidev->frm_st;
aidev->frm_st = ktime_get_ns();
@@ -1643,8 +1742,9 @@ enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis
u64 frm_hdntim = 0;
v4l2_dbg(1, rkaiisp_debug, &aidev->v4l2_dev,
"irq val: 0x%x, run_idx %d, model_runcnt %d\n",
mi_mis, aidev->run_idx, aidev->model_runcnt);
"irq val: 0x%x, run_idx %d, model_runcnt %d, parthdl %d, %d\n",
mi_mis, aidev->run_idx, aidev->model_runcnt,
aidev->parthdl_idx, aidev->parthdl_num);
if (mi_mis & AIISP_MI_ISR_BUSERR) {
v4l2_err(&aidev->v4l2_dev, "buserr 0x%x\n", mi_mis);
@@ -1657,11 +1757,17 @@ enum rkaiisp_irqhdl_ret rkaiisp_irq_hdl(struct rkaiisp_device *aidev, u32 mi_mis
rkaiisp_write(aidev, AIISP_MI_ICR, AIISP_MI_ISR_WREND, true);
aidev->isr_wrend_cnt++;
if (aidev->run_idx < aidev->model_runcnt - 1) {
if (aidev->run_idx + 1 < aidev->model_runcnt) {
aidev->run_idx++;
rkaiisp_run_cfg(aidev, aidev->run_idx);
rkaiisp_run_start(aidev);
return CONTINUE_RUN;
} else if (aidev->is_parthdl && (aidev->parthdl_idx + 1 < aidev->parthdl_num)) {
aidev->parthdl_idx++;
aidev->run_idx = 0;
rkaiisp_run_cfg(aidev, aidev->run_idx);
rkaiisp_run_start(aidev);
return CONTINUE_RUN;
}
aidev->frm_ed = ktime_get_ns();
@@ -1838,6 +1944,13 @@ static long rkaiisp_ioctl_default(struct file *file, void *fh,
case RKAIISP_CMD_GET_YNRBUF_INFO:
ret = rkaiisp_get_ynrbuf_info(aidev, arg);
break;
case RKAIISP_CMD_SET_MEMORY_MODE: {
enum rkaiisp_mem_mode *mem_mode = (enum rkaiisp_mem_mode *)arg;
aidev->mem_mode = *mem_mode;
ret = 0;
}
break;
default:
ret = -EINVAL;
}

View File

@@ -37,6 +37,8 @@
#define RKAIISP_SW_REG_SIZE 0x3000
#define RKAIISP_SW_MAX_SIZE (RKAIISP_SW_REG_SIZE * 2)
#define RKAIISP_AIRMS_BUF_MAXCNT 8
#define RKAIISP_AIRMS_MAX_WIDTH 4096
#define RKAIISP_AIRMS_EXTEND_PIXEL 16
#define RKAIISP_MIN(a, b) ((a) < (b) ? (a) : (b))
enum rkaiisp_irqhdl_ret {
@@ -121,10 +123,11 @@ struct rkaiisp_device {
struct rkaiisp_dummy_buffer *lastout_buf[RKAIISP_LASTOUT_BUF_CNT];
u32 outbuf_idx;
bool is_parthdl;
struct rkaiisp_rmsbuf_info rmsbuf;
struct rkaiisp_rmsbuf_info part_rmsbuf;
struct rkaiisp_dummy_buffer rms_inbuf[RKAIISP_AIRMS_BUF_MAXCNT];
struct rkaiisp_dummy_buffer rms_outbuf[RKAIISP_AIRMS_BUF_MAXCNT];
struct rkaiisp_dummy_buffer sigma_buf;
struct rkaiisp_dummy_buffer narmap_buf;
struct aiisp_aiynr_ybuf_cfg ynr_ybuf_cfg;
@@ -144,12 +147,17 @@ struct rkaiisp_device {
enum rkaiisp_exemode exemode;
enum rkaiisp_model_mode model_mode;
enum rkaiisp_hwstate hwstate;
enum rkaiisp_mem_mode mem_mode;
u32 para_size;
u32 max_runcnt;
u32 model_runcnt;
u32 run_idx;
u32 frame_id;
u32 parthdl_idx;
u32 parthdl_num;
u32 parthdl_image_oft;
u64 pre_frm_st;
u64 frm_st;
u64 frm_ed;
@@ -161,6 +169,7 @@ struct rkaiisp_device {
bool streamon;
bool showreg;
bool init_buf;
bool is_state_err;
};
extern int rkaiisp_debug;

View File

@@ -1968,8 +1968,9 @@ static void rkcif_rdbk_with_tools(struct rkcif_stream *stream,
unsigned long flags;
spin_lock_irqsave(&stream->tools_vdev->vbq_lock, flags);
if (stream->tools_vdev->state == RKCIF_STATE_STREAMING) {
list_add_tail(&active_buf->list, &stream->tools_vdev->buf_done_head);
if (stream->tools_vdev->state == RKCIF_STATE_STREAMING && active_buf) {
list_add_tail(&active_buf->list_tool, &stream->tools_vdev->buf_done_head);
active_buf->use_cnt = 2;
if (!work_busy(&stream->tools_vdev->work))
schedule_work(&stream->tools_vdev->work);
}
@@ -4058,7 +4059,7 @@ static int rkcif_csi_channel_init(struct rkcif_stream *stream,
channel->fmt_val == CSI_WRDDR_TYPE_RGB565)
channel->width = channel->width * fmt->bpp[0] / 8;
if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888)
if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888 && dev->chip_id < CHIP_RK3576_CIF)
channel->width /= 2;
/*
* rk cif don't support output yuyv fmt data
@@ -4763,9 +4764,9 @@ static int rkcif_csi_channel_set_v1(struct rkcif_stream *stream,
return 0;
}
val = rkcif_read_register(dev, CIF_REG_GLB_CTRL);
if (stream->sw_dbg_en) {
rkcif_write_register_and(dev, CIF_REG_GLB_CTRL,
~(u32)BIT(16));
val &= ~BIT(16);
v4l2_subdev_call(dev->active_sensor->sd,
core, ioctl,
RKCIF_CMD_SET_PPI_DATA_DEBUG,
@@ -4776,18 +4777,23 @@ static int rkcif_csi_channel_set_v1(struct rkcif_stream *stream,
RKCIF_CMD_SET_PPI_DATA_DEBUG,
&stream->sw_dbg_en);
}
if (dev->chip_id == CHIP_RK3588_CIF ||
dev->chip_id == CHIP_RV1106_CIF ||
dev->chip_id == CHIP_RK3562_CIF) {
val = GLB_RESET_IDI_EN_RK3588;
val |= GLB_RESET_IDI_EN_RK3588;
} else if (dev->chip_id == CHIP_RK3576_CIF) {
val = GLB_RESET_IDI_EN_RK3576;
val |= GLB_RESET_IDI_EN_RK3576;
val |= rkcif_get_split_dphy_mask_rk3576(dev);
} else if (dev->chip_id == CHIP_RV1103B_CIF) {
val = rkcif_get_split_dphy_mask_rv1103b(dev);
val |= rkcif_get_split_dphy_mask_rv1103b(dev);
}
rkcif_write_register_or(dev, CIF_REG_GLB_CTRL, val);
if (dev->chip_id == CHIP_RV1103B_CIF) {
if (rkcif_frm_toisp_protect)
val &= ~BIT(28);
else
val |= BIT(28);
}
rkcif_write_register(dev, CIF_REG_GLB_CTRL, val);
if (dev->terminal_sensor.hdmi_input_en) {
if (dev->chip_id == CHIP_RK3562_CIF ||
@@ -5075,8 +5081,13 @@ static int rkcif_csi_channel_set_rv1126b(struct rkcif_stream *stream,
CSI_DISABLE_CAPTURE);
return 0;
}
val = rkcif_get_split_mask_rv1126b(dev);
rkcif_write_register_or(dev, CIF_REG_GLB_CTRL, val);
val = rkcif_read_register(dev, CIF_REG_GLB_CTRL);
val |= rkcif_get_split_mask_rv1126b(dev);
if (rkcif_frm_toisp_protect)
val &= ~BIT(28);
else
val |= BIT(28);
rkcif_write_register(dev, CIF_REG_GLB_CTRL, val);
rkcif_write_register_and(dev, CIF_REG_MIPI_LVDS_INTSTAT,
~(CSI_START_INTSTAT(channel->id) |
CSI_DMA_END_INTSTAT(channel->id) |
@@ -6956,6 +6967,7 @@ void rkcif_do_stop_stream(struct rkcif_stream *stream,
kfifo_free(&stream->dcg_kfifo);
}
stream->crop_enable = false;
stream->crop_mask = 0;
stream->frame_loss = 0;
stream->is_fb_first_frame = true;
@@ -9778,6 +9790,7 @@ int rkcif_quick_stream_on(struct rkcif_device *dev, bool is_intr)
if (dev->sditf[0]->mode.rdbk_mode < RKISP_VICAP_RDBK_AIQ) {
for (i = 0; i < stream_num; i++) {
stream = &dev->stream[i];
stream->is_pause_stream = false;
if (stream->cifdev->hdr.hdr_mode == NO_HDR ||
(stream->cifdev->hdr.hdr_mode == HDR_X2 && stream->id == 1) ||
(stream->cifdev->hdr.hdr_mode == HDR_X3 && stream->id == 2)) {
@@ -9807,6 +9820,7 @@ int rkcif_quick_stream_on(struct rkcif_device *dev, bool is_intr)
RKISP_VICAP_CMD_MODE, &dev->sditf[0]->mode);
}
for (i = 0; i < stream_num; i++) {
dev->stream[i].is_pause_stream = false;
if (dev->sditf[0]->mode.rdbk_mode != RKISP_VICAP_RDBK_AIQ)
dev->stream[i].to_en_dma = RKCIF_DMAEN_BY_ISP;
else
@@ -11086,7 +11100,8 @@ static bool rkcif_is_csi2_err_trigger_reset(struct rkcif_timer *timer)
* or fs and fe had been not paired.
*/
if (stream->is_fs_fe_not_paired ||
stream->fs_cnt_in_single_frame > RKCIF_FS_DETECTED_NUM) {
(stream->fs_cnt_in_single_frame > RKCIF_FS_DETECTED_NUM &&
dev->chip_id < CHIP_RK3588_CIF)) {
is_triggered = true;
v4l2_info(&dev->v4l2_dev, "reset for fs & fe not paired\n");
}
@@ -11218,7 +11233,7 @@ static void rkcif_dynamic_crop(struct rkcif_stream *stream)
mbus->type == V4L2_MBUS_CCP2) {
struct csi_channel_info *channel = &cif_dev->channels[stream->id];
if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888)
if (channel->fmt_val == CSI_WRDDR_TYPE_RGB888 && cif_dev->chip_id < CHIP_RK3576_CIF)
crop_x = 3 * stream->crop[CROP_SRC_ACT].left / 2;
else if (channel->fmt_val == CSI_WRDDR_TYPE_RGB565)
crop_x = 2 * stream->crop[CROP_SRC_ACT].left;
@@ -13968,9 +13983,6 @@ static void rkcif_deal_sof(struct rkcif_device *cif_dev)
RKISP_VICAP_CMD_SOF, &sof);
}
if (cif_dev->chip_id < CHIP_RK3588_CIF)
detect_stream->fs_cnt_in_single_frame++;
if (cif_dev->sditf[0] &&
cif_dev->sditf[0]->mode.rdbk_mode >= RKISP_VICAP_RDBK_AIQ &&
(!detect_stream->dma_en) && cif_dev->chip_id < CHIP_RK3576_CIF)

View File

@@ -474,6 +474,7 @@ static void rkcif_tools_vb2_stop_streaming(struct vb2_queue *vq)
struct rkcif_device *dev = tools_vdev->cifdev;
struct rkcif_buffer *buf = NULL;
struct rkcif_tools_buffer *tools_buf;
struct rkcif_rx_buffer *rx_buf = NULL;
int ret = 0;
mutex_lock(&dev->tools_lock);
@@ -485,6 +486,12 @@ static void rkcif_tools_vb2_stop_streaming(struct vb2_queue *vq)
if (!ret) {
rkcif_tools_stop(tools_vdev);
tools_vdev->stopping = false;
while (!list_empty(&tools_vdev->buf_done_head)) {
rx_buf = list_first_entry(&tools_vdev->buf_done_head,
struct rkcif_rx_buffer, list_tool);
list_del(&rx_buf->list_tool);
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &rx_buf->dbufs, NULL);
}
}
/* release buffers */
if (tools_vdev->curr_buf)
@@ -710,9 +717,9 @@ retry_done_rdbk_buf:
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
if (!list_empty(&tools_vdev->buf_done_head)) {
buf = list_first_entry(&tools_vdev->buf_done_head,
struct rkcif_rx_buffer, list);
struct rkcif_rx_buffer, list_tool);
if (buf)
list_del(&buf->list);
list_del(&buf->list_tool);
}
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
if (!buf) {
@@ -724,12 +731,14 @@ retry_done_rdbk_buf:
if (tools_vdev->stopping) {
rkcif_tools_stop(tools_vdev);
tools_vdev->stopping = false;
if (buf)
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &buf->dbufs, NULL);
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
while (!list_empty(&tools_vdev->buf_done_head)) {
buf = list_first_entry(&tools_vdev->buf_done_head,
struct rkcif_rx_buffer, list);
if (buf)
list_del(&buf->list);
struct rkcif_rx_buffer, list_tool);
list_del(&buf->list_tool);
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &buf->dbufs, NULL);
}
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
wake_up(&tools_vdev->wq_stopped);
@@ -742,9 +751,13 @@ retry_done_rdbk_buf:
if (!tools_vdev->curr_buf || tools_vdev->state != RKCIF_STATE_STREAMING) {
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);
if (!list_empty(&tools_vdev->buf_done_head)) {
if (buf)
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &buf->dbufs, NULL);
spin_unlock_irqrestore(&stream->tools_vdev->vbq_lock, flags);
goto retry_done_rdbk_buf;
}
if (buf)
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &buf->dbufs, NULL);
spin_unlock_irqrestore(&tools_vdev->vbq_lock, flags);
return;
}
@@ -765,10 +778,14 @@ retry_done_rdbk_buf:
payload_size);
memcpy(dst, src, payload_size);
}
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &buf->dbufs, NULL);
tools_vdev->curr_buf->vb.sequence = buf->dbufs.sequence;
tools_vdev->curr_buf->vb.vb2_buf.timestamp = buf->dbufs.timestamp;
vb2_buffer_done(&tools_vdev->curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
tools_vdev->curr_buf = NULL;
} else {
if (buf)
v4l2_subdev_call(&dev->sditf[0]->sd, video, s_rx_buffer, &buf->dbufs, NULL);
}
spin_lock_irqsave(&tools_vdev->vbq_lock, flags);

View File

@@ -36,6 +36,10 @@ int rkcif_debug;
module_param_named(debug, rkcif_debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
bool rkcif_frm_toisp_protect = true;
module_param_named(toisp_protect, rkcif_frm_toisp_protect, bool, 0644);
MODULE_PARM_DESC(toisp_protect, "frame protect of toisp");
static char rkcif_version[RKCIF_VERNO_LEN];
module_param_string(version, rkcif_version, RKCIF_VERNO_LEN, 0444);
MODULE_PARM_DESC(version, "version number");

View File

@@ -232,6 +232,7 @@ struct rkcif_tools_buffer {
};
extern int rkcif_debug;
extern bool rkcif_frm_toisp_protect;
/*
* struct rkcif_sensor_info - Sensor infomations
@@ -478,12 +479,14 @@ enum rkcif_capture_mode {
struct rkcif_rx_buffer {
int buf_idx;
struct list_head list;
struct list_head list_tool;
struct list_head list_free;
struct rkisp_rx_buf dbufs;
struct rkcif_dummy_buffer dummy;
struct rkisp_thunderboot_shmem shmem;
u64 fe_timestamp;
bool is_init[RKCIF_MAX_DEV];
int use_cnt;
};
enum rkcif_dma_en_mode {

View File

@@ -282,6 +282,8 @@ static int csi2_start(struct csi2_dev *csi2)
else
host_type = RK_CSI_RXHOST;
csi2->irq1_timestamp = 0;
csi2->irq2_timestamp = 0;
for (i = 0; i < csi2->csi_info.csi_num; i++) {
csi_idx = csi2->csi_info.csi_idx[i];
ret |= csi2_hw_start(csi2->csi2_hw[csi_idx], host_type);
@@ -840,6 +842,7 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
char cur_str[CSI_ERRSTR_LEN] = {0};
char vc_info[CSI_VCINFO_LEN] = {0};
bool is_add_cnt = false;
u64 cur_timestamp = ktime_get_ns();
if (!csi2_hw) {
disable_irq_nosync(irq);
@@ -912,7 +915,7 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
}
if (val & CSIHOST_ERR1_ERR_ECC2) {
err_list = &csi2->err_list[RK_CSI2_ERR_CRC];
err_list = &csi2->err_list[RK_CSI2_ERR_ECC2];
err_list->cnt++;
is_add_cnt = true;
snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc2) ");
@@ -920,12 +923,17 @@ static irqreturn_t rk_csirx_irq1_handler(int irq, void *ctx)
}
if (val & CSIHOST_ERR1_ERR_CTRL) {
err_list = &csi2->err_list[RK_CSI2_ERR_CTRL];
err_list->cnt++;
csi2_find_err_vc((val >> 16) & 0xf, vc_info);
snprintf(cur_str, CSI_ERRSTR_LEN, "(ctrl,vc:%s) ", vc_info);
csi2_err_strncat(err_str, cur_str);
}
pr_err("(0x%x)MIPI_CSI2 ERR1:0x%x %s\n", (u32)csi2_hw->res->start, val, err_str);
if (csi2->irq1_timestamp == 0 || cur_timestamp - csi2->irq1_timestamp > 1000000000) {
csi2->irq1_timestamp = cur_timestamp;
pr_err("(0x%x)MIPI_CSI2 ERR1:0x%x %s\n", (u32)csi2_hw->res->start, val, err_str);
}
if (is_add_cnt) {
csi2->err_list[RK_CSI2_ERR_ALL].cnt++;
@@ -946,16 +954,24 @@ static irqreturn_t rk_csirx_irq2_handler(int irq, void *ctx)
{
struct device *dev = ctx;
struct csi2_hw *csi2_hw = dev_get_drvdata(dev);
struct csi2_dev *csi2 = NULL;
u32 val;
char cur_str[CSI_ERRSTR_LEN] = {0};
char err_str[CSI_ERRSTR_LEN] = {0};
char vc_info[CSI_VCINFO_LEN] = {0};
u64 cur_timestamp = ktime_get_ns();
if (!csi2_hw) {
disable_irq_nosync(irq);
return IRQ_HANDLED;
}
csi2 = csi2_hw->csi2;
if (!csi2) {
disable_irq_nosync(irq);
return IRQ_HANDLED;
}
val = read_csihost_reg(csi2_hw->base, CSIHOST_ERR2);
if (val) {
if (val & CSIHOST_ERR2_PHYERR_ESC) {
@@ -983,7 +999,10 @@ static irqreturn_t rk_csirx_irq2_handler(int irq, void *ctx)
csi2_err_strncat(err_str, cur_str);
}
pr_err("(0x%x)MIPI_CSI2 ERR2:0x%x %s\n", (u32)csi2_hw->res->start, val, err_str);
if (csi2->irq2_timestamp == 0 || cur_timestamp - csi2->irq2_timestamp > 1000000000) {
csi2->irq2_timestamp = cur_timestamp;
pr_err("(0x%x)MIPI_CSI2 ERR2:0x%x %s\n", (u32)csi2_hw->res->start, val, err_str);
}
}
return IRQ_HANDLED;

View File

@@ -113,6 +113,8 @@ enum csi2_err {
RK_CSI2_ERR_FRM_SEQ_ERR,
RK_CSI2_ERR_CRC_ONCE,
RK_CSI2_ERR_CRC,
RK_CSI2_ERR_ECC2,
RK_CSI2_ERR_CTRL,
RK_CSI2_ERR_ALL,
RK_CSI2_ERR_MAX
};
@@ -176,6 +178,8 @@ struct csi2_dev {
struct rkcif_csi_info csi_info;
const char *dev_name;
int sw_dbg;
u64 irq1_timestamp;
u64 irq2_timestamp;
};
struct csi2_hw {

Some files were not shown because too many files have changed in this diff Show More