Merge commit '8127940715d154ad28fc1764e5dd6233517fe3b6'

* commit '8127940715d154ad28fc1764e5dd6233517fe3b6':
  drm/rockchip: vop2: add support dovi mode config
  drm/rockchip: vop2: update mode changed for dovi
  drm/rockchip: vop2: dynamic enable/disable dovi core
  drm/rockchip: vop2: add aclk reset when exit from dovi mode
  drm/rockchip: vop2: add support force DOVI mode
  gpio: rockchip: release clk correctly when error
  arm64: dts: rockchip: add rk3576 evb1 v10 dv dts
  arm64: configs: add rk3576_dv.config
  power: supply: rockchip-charger-manager: Supports charging via docking station
  iio: imu: inv_icm42670: fix suspend/resume handling
  iio: imu: inv_icm42670: use gpiod_to_irq to get interrupts instead

Change-Id: I30960350731c4e5df428f4eddab0f23d819eb7e1
This commit is contained in:
Tao Huang
2025-03-10 19:25:34 +08:00
11 changed files with 1395 additions and 95 deletions

View File

@@ -251,6 +251,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-ebook-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-ebook-x3-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-android9.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-dv.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-edp-NV140QUM-N61.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-hdmi2dp.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-evb1-v10-image-reverse-demo.dtb

View File

@@ -0,0 +1,871 @@
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2024 Rockchip Electronics Co., Ltd.
*
*/
/dts-v1/;
#include <dt-bindings/display/media-bus-format.h>
#include "rk3576s.dtsi"
#include "rk3576s-evb1.dtsi"
#include "rk3576-linux.dtsi"
/ {
model = "Rockchip RK3576 EVB1 V10 DV Board";
compatible = "rockchip,rk3576-evb1-v10-dv", "rockchip,rk3576";
/delete-node/ vbus5v0-typec;
/delete-node/ vcc-mipicsi0-regulator;
/delete-node/ vcc-mipicsi1-regulator;
bat: battery {
compatible = "simple-battery";
charge-full-design-microamp-hours = <8000000>;
precharge-current-microamp = <180000>;
precharge-upper-limit-microvolt = <3600000>;
charge-term-current-microamp = <300000>;
constant-charge-current-max-microamp = <10000000>;
constant-charge-voltage-max-microvolt = <4350000>;
factory-internal-resistance-micro-ohms = <80>;
voltage-max-design-microvolt = <4350000>;
voltage-min-design-microvolt = <3000000>;
};
charge-animation {
compatible = "rockchip,uboot-charge";
rockchip,uboot-charge-on = <0>;
rockchip,android-charge-on = <1>;
rockchip,uboot-low-power-voltage = <3450>;
rockchip,screen-on-voltage = <3500>;
rockchip,auto-wakeup-interval = <5>;
rockchip,uboot-exit-charge-level = <2>;
rockchip,uboot-exit-charge-voltage = <3500>;
rockchip,uboot-exit-charge-auto = <1>;
status = "disabled";
};
rk730_sound: rk730-sound {
status = "okay";
compatible = "rockchip,multicodecs-card";
rockchip,card-name = "rockchip-rk730";
spk-con-gpio = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
rockchip,pre-power-on-delay-ms = <30>;
rockchip,post-power-down-delay-ms = <40>;
rockchip,format = "i2s";
rockchip,mclk-fs = <256>;
rockchip,cpu = <&sai0>;
rockchip,codec = <&rk730>;
rockchip,audio-routing =
"Headphone", "LOUT1",
"Headphone", "ROUT1",
"Speaker", "LOUT2",
"Speaker", "ROUT2",
"Headphone", "Headphone Power",
"Headphone", "Headphone Power",
"Speaker", "Speaker Power",
"Speaker", "Speaker Power",
"MIC2", "Main Mic",
"MIC1", "Headset Mic";
};
};
&backlight {
pwms = <&pwm1_6ch_3 0 25000 0>;
status = "okay";
};
&chosen {
bootargs = "earlycon=uart8250,mmio32,0x2ad40000 console=ttyFIQ0 \
ubi.mtd=3 root=ubi0:rootfs rootfstype=ubifs rw rootwait \
rcupdate.rcu_expedited=1 rcu_nocbs=all isolcpus=3 nohz_full=3 \
snd_aloop.index=7 snd_aloop.use_raw_jiffies=1";
};
&CPU_SLEEP {
status = "disabled";
};
&csi2_dcphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_in_ucam0: endpoint@1 {
reg = <1>;
remote-endpoint = <&imx386_out0>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidcphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi0_csi2_input>;
};
};
};
};
&display_subsystem {
status = "okay";
};
&dp {
status = "okay";
};
&dp0 {
status = "okay";
};
&dp0_in_vp2 {
status = "okay";
};
&dsi {
status = "disabled";
};
&es8388_sound {
status = "disabled";
};
&gpio4 {
interrupt-affinity = <&cpu_l0>, <&cpu_l3>, <&cpu_l0>, <&cpu_l0>;
interrupt-pins = <0>,
<RK_PIN_TO_BIT(RK_PB4)>,
<0>,
<0>;
};
&gt1x {
status = "disabled";
};
&hdmi {
status = "disabled";
};
&hdmi_in_vp0 {
status = "disabled";
};
&hdptxphy_hdmi {
status = "disabled";
};
&i2c2 {
status = "okay";
/delete-node/ husb311@4e;
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
vbus-supply = <&vbus5v0_typec>;
wakeup-source;
status = "okay";
port {
usbc0_role_sw: endpoint {
remote-endpoint = <&usb_drd0_role_switch>;
};
};
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
power-role = "dual";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
source-pdos =
<PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
mode-switch = <&dp>;
altmodes {
#address-cells = <1>;
#size-cells = <0>;
altmode@0 {
reg = <0>;
svid = <0xff01>;
vdo = <0xffffffff>;
};
};
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
usbc0_orien_sw: endpoint {
remote-endpoint = <&usbdp_phy_orientation_switch>;
};
};
port@1 {
reg = <1>;
dp_altmode_mux: endpoint {
remote-endpoint = <&usbdp_phy_dp_altmode_mux>;
};
};
};
};
};
};
&i2c3 {
status = "disabled";
};
&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c4m1_xfer>;
cw221X@64 {
compatible = "cellwise,cw221X";
reg = <0x64>;
status = "okay";
cw,user_rsense = <2000>;
cellwise,battery-profile = /bits/ 8
<0x5A 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0xAA 0xB4 0xB7 0xBB 0xA7 0x9F 0xE3 0xD6
0xD0 0xFF 0xF5 0xA4 0x89 0x6D 0x5B 0x51
0x48 0x47 0x45 0xCC 0xC5 0xD8 0x7E 0xD3
0xCD 0xCC 0xCB 0xCA 0xC3 0xBF 0xDD 0x9A
0xB7 0xB9 0xB0 0x99 0x8A 0x82 0x76 0x69
0x61 0x63 0x77 0x8E 0xA5 0x7F 0x55 0x5F
0x20 0x00 0xAB 0x10 0x00 0xA2 0xEC 0x00
0x00 0x00 0x64 0x26 0xB1 0xCE 0x00 0x00
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x11>;
};
sc89601: sc89601@6b {
compatible = "sc,sc89601";
reg = <0x6b>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&charger_ok>;
interrupt-parent = <&gpio0>;
interrupts = <RK_PD2 IRQ_TYPE_EDGE_FALLING>; /* IRQ_TYPE_LEVEL_LOW>;*/
charger-phandle = <&usbc0>;
sc,battery-regulation-voltage = <4350000>; /* 4200000,4.2V , 4350000, 4232000*/
sc,charge-current = <3000000>; /*2040000,* 2.040A, 3000000 */
sc,termination-current = <180000>; /* 180mA, 180000 */
sc,precharge-current = <180000>; /* 180mA */
sc,minimum-sys-voltage = <3400000>; /*3500000, 3.5V */
sc,boost-voltage = <5000000>; /*5100000, 5.1V */
sc,boost-max-current = <1500000>; /*1200000, 1200mA */
sc,use-stat-pin = <0>; /* enable stat pin */
sc,boost-freq = <0>; /* 1.5MHz */
//monitored-battery = <&bat>;
regulators {
otg-en-pin = <&gpio0 RK_PD3 GPIO_ACTIVE_HIGH>;
vbus5v0_typec: vbus5v0-typec {
regulator-compatible = "otg-vbus";
regulator-name = "vbus5v0_typec";
};
};
};
};
&i2c5 {
status = "okay";
pinctrl-0 = <&i2c5m2_xfer>;
imx386: imx386@1a {
compatible = "sony,imx386";
reg = <0x1a>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M0>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&cam_clk0m1_clk0>; // GPIO2 D2
power-domains = <&power RK3576_PD_VI>;
avdd-supply = <&vcc_mipidcphy0>;
reset-gpios = <&gpio2 RK_PD6 GPIO_ACTIVE_HIGH>;
pwdn-gpios = <&gpio2 RK_PD7 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "CMK-OT2022-PX1";
rockchip,camera-module-lens-name = "IR0147-50IRC-8M-F20";
port {
imx386_out0: endpoint {
remote-endpoint = <&mipi_in_ucam0>;
data-lanes = <1 2 3 4>;
};
};
};
};
&i2c7 {
status = "disabled";
};
&i2c9 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c9m2_xfer>;
rk730: rk730@16 {
#sound-dai-cells = <0>;
compatible = "rockchip,rk730";
reg = <0x16>;
clocks = <&mclkout_sai0>;
clock-names = "mclk";
assigned-clocks = <&mclkout_sai0>;
assigned-clock-rates = <12288000>;
pinctrl-names = "default";
pinctrl-0 = <&sai0m0_mclk>;
status = "okay";
};
};
&little_core_thermal {
trips {
threshold: trip-point-0 {
temperature = <105000>;
hysteresis = <2000>;
type = "passive";
};
target: trip-point-1 {
temperature = <105000>;
hysteresis = <2000>;
type = "passive";
};
little_core_crit: little-core-crit {
/* millicelsius */
temperature = <115000>;
/* millicelsius */
hysteresis = <2000>;
type = "critical";
};
};
};
&mipi0_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidcphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in0>;
};
};
};
};
&mipidcphy0_pwr {
rockchip,pins =
/* camera power en */
<2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
};
/*
* The pins of pcie1 and mcu_panel are multiplexed
*/
&pcie0 {
status = "disabled";
};
&pinctrl {
inv {
inv_int1: inv-int1 {
rockchip,pins =
<4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
charger {
charger_ok: charger_ok {
rockchip,pins =
<0 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>,
<0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
usb {
usb_host_pwren: usb-host-pwren {
rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
};
usb_otg0_pwren: usb-otg0-pwren {
rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>;
};
usbc0_int: usbc0-int {
rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
};
&pwm1_6ch_3 {
pinctrl-names = "active";
pinctrl-0 = <&pwm1m3_ch3>;
status = "okay";
};
&rgb {
status = "okay";
rockchip,data-sync-bypass;
pinctrl-names = "default";
/*
* rgb3x8_pins_m0/rgb3x8_pins_m1 for RGB3x8(8bit)
* rgb565_pins for RGB565(16bit)
*/
pinctrl-0 = <&rgb3x8_pins_m0>;
/*
* 240x320 RGB/MCU screen DT20QV063
*/
mcu_panel: mcu-panel {
/*
* MEDIA_BUS_FMT_RGB888_3X8 for RGB3x8(8bit)
* MEDIA_BUS_FMT_RGB565_1X16 for RGB565(16bit)
* MEDIA_BUS_FMT_RGB565_2X8_LE for RGB565(8bit)
*/
bus-format = <MEDIA_BUS_FMT_RGB565_2X8_LE>;
backlight = <&backlight>; // dummy bl configuration
enable-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
enable-delay-ms = <20>;
reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
reset-delay-ms = <200>;
prepare-delay-ms = <10>;
unprepare-delay-ms = <20>;
disable-delay-ms = <20>;
init-delay-ms = <120>;
width-mm = <217>;
height-mm = <136>;
// type:0 is cmd, 1 is data
panel-init-sequence = [
//type delay num val1 val2 val3
// private access
00 00 01 fd
01 00 01 06
01 00 01 08
00 00 01 61
01 00 01 07
01 00 01 07
00 00 01 73
01 00 01 70
00 00 01 73
01 00 01 00
00 00 01 61
01 00 01 07
01 00 01 07
// bias setting
00 00 01 62
01 00 01 00
01 00 01 44
01 00 01 40
// vsp
00 00 01 65
01 00 01 08
01 00 01 10
01 00 01 21
// vsn
00 00 01 66
01 00 01 08
01 00 01 10
01 00 01 21
// add source neg time
00 00 01 67
01 00 01 21
01 00 01 40
// gamma vap/van
00 00 01 68
01 00 01 70
01 00 01 37
01 00 01 2a
01 00 01 16
// frame rate
00 00 01 b1
01 00 01 0f
01 00 01 02
01 00 01 04
00 00 01 b4
01 00 01 01
// porch
00 00 01 b5
01 00 01 02
01 00 01 02
01 00 01 0a
01 00 01 14
// display function
00 00 01 b6
01 00 01 44
01 00 01 01
01 00 01 9f
01 00 01 00
01 00 01 02
// source
00 00 01 e6
01 00 01 00
01 00 01 ff
00 00 01 e7
01 00 01 01
01 00 01 04
01 00 01 03
01 00 01 03
01 00 01 00
01 00 01 12
00 00 01 e8
01 00 01 00
01 00 01 70
01 00 01 00
// gate
00 00 01 ec
01 00 01 52
// gamma_sel
00 00 01 df
01 00 01 11
// gamma test1
00 00 01 e0
01 00 01 07
01 00 01 07
01 00 01 0a
01 00 01 13
01 00 01 0e
01 00 01 11
01 00 01 11
01 00 01 19
00 00 01 e3
01 00 01 12
01 00 01 0f
01 00 01 11
01 00 01 0e
01 00 01 10
01 00 01 09
01 00 01 05
01 00 01 06
00 00 01 e1
01 00 01 2a
01 00 01 71
00 00 01 e4
01 00 01 6b
01 00 01 2a
00 00 01 e2
01 00 01 00
01 00 01 13
01 00 01 17
01 00 01 31
01 00 01 36
01 00 01 3f
00 00 01 e5
01 00 01 3f
01 00 01 36
01 00 01 32
01 00 01 17
01 00 01 13
01 00 01 00
00 00 01 f6
01 00 01 01
01 00 01 30
01 00 01 00
01 00 01 00
00 00 01 f1
01 00 01 01 //te
01 00 01 01 //01
01 00 01 20 //02
00 00 01 fd
01 00 01 fa
01 00 01 fc
00 00 01 3a
01 00 01 55
00 00 01 35
01 00 01 00
00 00 01 36
01 00 01 00
// exit sleep
00 c8 01 11
// display on
00 14 01 29
00 00 01 2a
01 00 01 00
01 00 01 00
01 00 01 00
01 00 01 ef
00 00 01 2b
01 00 01 00
01 00 01 00
01 00 01 01
01 00 01 3f
00 00 01 2c
];
panel-exit-sequence = [
//type delay num val1 val2 val3
// display off
00 14 01 28
// enter sleep
00 c8 01 10
];
display-timings {
native-mode = <&kd050fwfba002_timing>;
kd050fwfba002_timing: timing0 {
/*
* 7840125 for frame rate 45Hz
* 10453500 for frame rate 60Hz
*/
clock-frequency = <2742750>;
hactive = <240>;
vactive = <320>;
hback-porch = <10>;
hfront-porch = <5>;
vback-porch = <10>;
vfront-porch = <5>;
hsync-len = <10>;
vsync-len = <10>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <1>;
};
};
port {
panel_in_rgb: endpoint {
remote-endpoint = <&rgb_out_panel>;
};
};
};
ports {
rgb_out: port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
rgb_out_panel: endpoint@0 {
reg = <0>;
remote-endpoint = <&panel_in_rgb>;
};
};
};
};
&rgb_in_vp1 {
status = "okay";
};
&route_dp0 {
status = "okay";
};
&route_dsi {
status = "disabled";
};
&route_hdmi {
status = "disabled";
};
&route_rgb {
status = "okay";
connect = <&vp1_out_rgb>;
};
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds {
status = "okay";
port {
cif_mipi_in0: endpoint {
remote-endpoint = <&mipi0_csi2_output>;
};
};
};
&rkcif_mipi_lvds_sditf {
status = "okay";
port {
mipi_lvds_sditf: endpoint {
remote-endpoint = <&isp_vir0>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkisp_vir0 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds_sditf>;
};
};
};
&rkisp_vir0_sditf {
status = "okay";
};
&rkvpss {
status = "okay";
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir0 {
status = "okay";
};
&sai0 {
status = "okay";
pinctrl-0 = <&sai0m0_lrck
&sai0m0_sclk
&sai0m0_sdi0
&sai0m0_sdo0>;
};
/*
* The pins of sai1 and mcu_panel are multiplexed
*/
&sai1 {
status = "disabled";
};
&sfc0 {
status = "okay";
flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <80000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&spi4 {
status = "okay";
max-freq = <24000000>;
pinctrl-names = "default";
pinctrl-0 = <&spi4m2_csn0 &spi4m2_pins &inv_int1>;
icm42670: icm42670@0 {
compatible = "invensense,icm42670";
reg = <0x0>;
spi-max-frequency = <24000000>;
spi-cpha;
spi-cpol;
vdd-supply = <&vcc_3v3_s0>;
drive-open-drain = <1>;
int1-gpio = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
interrupt-parent = <&gpio4>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
status = "okay";
};
};
&usbdp_phy {
sbu1-dc-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
};
&vcc_mipidcphy0 {
gpio = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
};
&vp0 {
status = "disabled";
};
&vp1 {
mcu-timing {
mcu-pix-total = <5>;
mcu-cs-pst = <1>;
mcu-cs-pend = <4>;
mcu-rw-pst = <2>;
mcu-rw-pend = <3>;
mcu-hold-mode = <0>;
};
};
&vdd_0v75_s3 {
regulator-min-microvolt = <550000>;
};

View File

@@ -0,0 +1,137 @@
# CONFIG_ATA is not set
CONFIG_AX88796B_PHY=y
CONFIG_BATTERY_CW221X=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BT is not set
# CONFIG_CAN is not set
# CONFIG_CGROUPS is not set
CONFIG_CHARGER_SC89601=y
# CONFIG_CPU_PX30 is not set
# CONFIG_CPU_RK1808 is not set
# CONFIG_CPU_RK3328 is not set
# CONFIG_CPU_RK3399 is not set
# CONFIG_CPU_RK3528 is not set
# CONFIG_CPU_RK3562 is not set
# CONFIG_CPU_RK3568 is not set
# CONFIG_CPU_RK3588 is not set
# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_DEBUG_MISC is not set
# CONFIG_DTC_SYMBOLS is not set
# CONFIG_DVB_DYNAMIC_MINORS is not set
# CONFIG_DVB_NET is not set
# CONFIG_ETHERNET is not set
CONFIG_EXFAT_FS=y
# CONFIG_EXT4_FS is not set
CONFIG_FAT_DEFAULT_IOCHARSET="cp936"
# CONFIG_FTRACE is not set
# CONFIG_I3C is not set
# CONFIG_IKCONFIG is not set
CONFIG_INV_ICM42670_SPI=y
# CONFIG_ISO9660_FS is not set
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_MEDIA_USB_SUPPORT is not set
# CONFIG_MOTORCOMM_PHY is not set
# CONFIG_MTD_OF_PARTS is not set
# CONFIG_MTD_SPI_NAND_ATO is not set
# CONFIG_MTD_SPI_NAND_BIWIN is not set
# CONFIG_MTD_SPI_NAND_DEVICE_AUTOSELECT is not set
# CONFIG_MTD_SPI_NAND_DOSILICON is not set
# CONFIG_MTD_SPI_NAND_ESMT is not set
# CONFIG_MTD_SPI_NAND_ETRON is not set
# CONFIG_MTD_SPI_NAND_FORESEE is not set
# CONFIG_MTD_SPI_NAND_GSTO is not set
# CONFIG_MTD_SPI_NAND_HIKSEMI is not set
# CONFIG_MTD_SPI_NAND_HYF is not set
# CONFIG_MTD_SPI_NAND_JSC is not set
# CONFIG_MTD_SPI_NAND_MACRONIX is not set
# CONFIG_MTD_SPI_NAND_MICRON is not set
# CONFIG_MTD_SPI_NAND_PARAGON is not set
# CONFIG_MTD_SPI_NAND_SILICONGO is not set
# CONFIG_MTD_SPI_NAND_SKYHIGH is not set
# CONFIG_MTD_SPI_NAND_TOSHIBA is not set
# CONFIG_MTD_SPI_NAND_UNIM is not set
# CONFIG_MTD_SPI_NAND_WINBOND is not set
# CONFIG_MTD_SPI_NAND_XINCUN is not set
# CONFIG_MTD_SPI_NAND_XTX is not set
# CONFIG_MTD_SPI_NAND_ZBIT is not set
# CONFIG_MTD_SPI_NOR is not set
CONFIG_MTD_UBI_BLOCK=y
# CONFIG_NAMESPACES is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_PCI is not set
CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=12
# CONFIG_PROFILING is not set
# CONFIG_RADIO_ADAPTERS is not set
# CONFIG_RCU_TRACE is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_RELAY is not set
# CONFIG_RK630_PHY is not set
CONFIG_ROCKCHIP_CHARGER_MANAGER=y
# CONFIG_ROCKCHIP_PHY is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SECURITYFS is not set
# CONFIG_SLUB_DEBUG is not set
CONFIG_SND_ALOOP=y
CONFIG_SND_SOC_RK730=y
# CONFIG_STACKTRACE is not set
# CONFIG_STRICT_DEVMEM is not set
# CONFIG_USB_RTL8150 is not set
CONFIG_USB_USBNET=y
# CONFIG_VHOST_MENU is not set
CONFIG_VIDEO_IMX386=y
# CONFIG_VIDEO_LT6911UXC is not set
# CONFIG_VIDEO_LT6911UXE is not set
# CONFIG_VIDEO_LT7911D is not set
# CONFIG_VIDEO_OS04A10 is not set
# CONFIG_VIDEO_OV4689 is not set
# CONFIG_VIDEO_OV50C40 is not set
# CONFIG_VIDEO_OV5695 is not set
# CONFIG_VIDEO_OV7251 is not set
# CONFIG_VIDEO_RK_IRCUT is not set
# CONFIG_VIDEO_SC4336 is not set
# CONFIG_VIRTIO_MENU is not set
# CONFIG_XFS_FS is not set
CONFIG_EXFAT_DEFAULT_IOCHARSET="cp936"
CONFIG_INV_ICM42670=y
CONFIG_NO_IOPORT_MAP=y
CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP=y
# CONFIG_USB_ALI_M5632 is not set
# CONFIG_USB_AN2720 is not set
CONFIG_USB_ARMLINUX=y
CONFIG_USB_BELKIN=y
# CONFIG_USB_EPSON2888 is not set
# CONFIG_USB_KC2190 is not set
# CONFIG_USB_NET_AQC111 is not set
CONFIG_USB_NET_AX88179_178A=y
CONFIG_USB_NET_AX8817X=y
CONFIG_USB_NET_CDCETHER=y
# CONFIG_USB_NET_CDC_EEM is not set
# CONFIG_USB_NET_CDC_MBIM is not set
CONFIG_USB_NET_CDC_NCM=y
CONFIG_USB_NET_CDC_SUBSET=y
CONFIG_USB_NET_CDC_SUBSET_ENABLE=y
# CONFIG_USB_NET_CH9200 is not set
# CONFIG_USB_NET_CX82310_ETH is not set
# CONFIG_USB_NET_DM9601 is not set
# CONFIG_USB_NET_GL620A is not set
# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
# CONFIG_USB_NET_INT51X1 is not set
# CONFIG_USB_NET_KALMIA is not set
# CONFIG_USB_NET_MCS7830 is not set
CONFIG_USB_NET_NET1080=y
# CONFIG_USB_NET_PLUSB is not set
# CONFIG_USB_NET_QMI_WWAN is not set
# CONFIG_USB_NET_RNDIS_HOST is not set
# CONFIG_USB_NET_SMSC75XX is not set
# CONFIG_USB_NET_SMSC95XX is not set
# CONFIG_USB_NET_SR9700 is not set
# CONFIG_USB_NET_SR9800 is not set
CONFIG_USB_NET_ZAURUS=y
CONFIG_USB_RTL8153_ECM=y
# CONFIG_USB_SIERRA_NET is not set
# CONFIG_USB_VL600 is not set

View File

@@ -1140,7 +1140,7 @@ static int rockchip_gpio_probe(struct platform_device *pdev)
ret = rockchip_gpio_parse_irqs(pdev, bank);
if (ret < 0)
return ret;
goto err_clk;
rockchip_gpio_init_cpuhp();
/*
@@ -1213,6 +1213,7 @@ err_unlock:
rockchip_gpio_remove_cpuhp();
mutex_unlock(&bank->deferred_lock);
err_clk:
clk_disable_unprepare(bank->clk);
clk_disable_unprepare(bank->db_clk);

View File

@@ -397,3 +397,61 @@ int rockchip_drm_debugfs_add_dclk_rate(struct drm_crtc *crtc, struct dentry *roo
return 0;
}
static int rockchip_drm_debugfs_dovi_mode_show(struct seq_file *s, void *data)
{
seq_puts(s, " Mode0: normal mode\n");
seq_puts(s, " echo 0 > /sys/kernel/debug/dri/0/video_port0/dovi_mode\n");
seq_puts(s, " Mode1: disable aclk reset when enter dovi\n");
seq_puts(s, " echo 1 > /sys/kernel/debug/dri/0/video_port0/dovi_mode\n");
return 0;
}
static int rockchip_drm_debugfs_dovi_mode_open(struct inode *inode, struct file *file)
{
struct drm_crtc *crtc = inode->i_private;
return single_open(file, rockchip_drm_debugfs_dovi_mode_show, crtc);
}
static ssize_t rockchip_drm_debugfs_dovi_mode_write(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
struct seq_file *s = file->private_data;
struct drm_crtc *crtc = s->private;
struct rockchip_drm_private *private = crtc->dev->dev_private;
u8 mode;
if (len != 2) {
DRM_INFO("Unsupported dovi mode\n");
return -EINVAL;
}
if (kstrtou8_from_user(ubuf, len, 0, &mode))
return -EFAULT;
private->dovi_mode = mode;
return len;
}
static const struct file_operations rockchip_drm_debugfs_dovi_mode_fops = {
.owner = THIS_MODULE,
.open = rockchip_drm_debugfs_dovi_mode_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
.write = rockchip_drm_debugfs_dovi_mode_write,
};
int rockchip_drm_debugfs_add_dovi_mode(struct drm_crtc *crtc, struct dentry *root)
{
struct dentry *ent;
ent = debugfs_create_file("dovi_mode", 0644, root, crtc,
&rockchip_drm_debugfs_dovi_mode_fops);
if (!ent)
DRM_ERROR("Failed to add dovi_mode for debugfs\n");
return 0;
}

View File

@@ -38,6 +38,7 @@ rockchip_drm_crtc_dump_plane_buffer(struct drm_crtc *crtc)
int rockchip_drm_debugfs_add_color_bar(struct drm_crtc *crtc, struct dentry *root);
int rockchip_drm_debugfs_add_regs_write(struct drm_crtc *crtc, struct dentry *root);
int rockchip_drm_debugfs_add_dclk_rate(struct drm_crtc *crtc, struct dentry *root);
int rockchip_drm_debugfs_add_dovi_mode(struct drm_crtc *crtc, struct dentry *root);
#else
static inline int
rockchip_drm_add_dump_buffer(struct drm_crtc *crtc, struct dentry *root)
@@ -68,6 +69,12 @@ rockchip_drm_debugfs_add_dclk_rate(struct drm_crtc *crtc, struct dentry *root)
{
return 0;
}
static inline int
rockchip_drm_debugfs_add_dovi_mode(struct drm_crtc *crtc, struct dentry *root)
{
return 0;
}
#endif
#endif

View File

@@ -595,6 +595,10 @@ struct rockchip_drm_private {
*/
struct mutex ovl_lock;
bool need_ovl_lock;
/**
* @dovi_mode: dovi mode from userspace for dovi test.
*/
u8 dovi_mode;
struct rockchip_drm_vcnt vcnt[ROCKCHIP_MAX_CRTC];
struct rockchip_drm_error_event error_event;

View File

@@ -4869,22 +4869,44 @@ static void vop2_dovi_enable(struct drm_crtc *crtc)
struct hdr_extend *hdr_data;
int i = 0;
if (vp->dovi_hdr_en)
return;
if (!vcstate->hdr_ext_data)
goto DISABLE_DOVI;
hdr_data = (struct hdr_extend *)vcstate->hdr_ext_data->data;
if (!hdr_data)
return;
if (!hdr_data || hdr_data->hdr_type != HDR_DOVI)
goto DISABLE_DOVI;
dovi_data = &hdr_data->dovi_data;
for (i = 0; i < vop2_data->dovi->nr_dovi_cores; i++) {
dovi_core = &vop2->dovi_cores[i];
if (vop2_check_dovi_core_enabled(dovi_core->id, dovi_data->valid))
if (vop2_check_dovi_core_enabled(dovi_core->id, dovi_data->valid)) {
VOP_MODULE_SET(vop2, dovi_core, enable, 1);
} else {
VOP_MODULE_SET(vop2, dovi_core, enable, 0);
VOP_MODULE_SET(vop2, dovi_core, lut_update, 0);
if (dovi_core->id == 2)
VOP_MODULE_SET(vop2, dovi_core, dly_en, 0);
}
}
vp->dovi_hdr_en = true;
DRM_DEV_INFO(vop2->dev, "vp%d dovi enabled\n", vp->id);
DRM_DEV_DEBUG(vop2->dev, "vp%d dovi enabled\n", vp->id);
return;
DISABLE_DOVI:
if (!vp->dovi_hdr_en)
return;
for (i = 0; i < vop2_data->dovi->nr_dovi_cores; i++) {
dovi_core = &vop2->dovi_cores[i];
VOP_MODULE_SET(vop2, dovi_core, enable, 0);
VOP_MODULE_SET(vop2, dovi_core, lut_update, 0);
if (dovi_core->id == 2)
VOP_MODULE_SET(vop2, dovi_core, dly_en, 0);
}
}
static int vop2_dovi_init(struct drm_crtc *crtc)
@@ -4979,6 +5001,13 @@ static void vop2_dovi_post_disable(struct drm_crtc *crtc)
vp->dovi_hdr_mode = false;
vp->dovi_hdr_en = false;
vp->dovi_hdr_in = false;
/**
* The burr of the vsync signal maybe lead to core1 work abnormally,
* so add aclk reset when exit from dovi mode.
*/
vop2_clk_reset(vop2->axi_rst);
drm_info(vop2, "vp%d dovi disabled\n", vp->id);
}
@@ -5653,7 +5682,6 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
VOP_MODULE_SET(vop2, vp, hdr_lut_update_en, 0);
vop2_dovi_pre_disable(crtc);
vop2_disable_all_planes_for_crtc(crtc);
vop2_dovi_post_disable(crtc);
if (vop2->dscs[vcstate->dsc_id].enabled &&
vop2->dscs[vcstate->dsc_id].attach_vp_id == vp->id &&
@@ -5742,6 +5770,7 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
vop2_dsp_hold_valid_irq_disable(crtc);
vop2_dovi_post_disable(crtc);
vop2_disable(crtc);
vop2->active_vp_mask &= ~BIT(vp->id);
@@ -8399,6 +8428,7 @@ static int vop2_crtc_debugfs_init(struct drm_minor *minor, struct drm_crtc *crtc
rockchip_drm_debugfs_add_color_bar(crtc, vop2->debugfs);
rockchip_drm_debugfs_add_regs_write(crtc, vop2->debugfs);
rockchip_drm_debugfs_add_dclk_rate(crtc, vop2->debugfs);
rockchip_drm_debugfs_add_dovi_mode(crtc, vop2->debugfs);
#endif
for (i = 0; i < ARRAY_SIZE(vop2_debugfs_files); i++)
vop2->debugfs_files[i].data = vop2;
@@ -10607,23 +10637,56 @@ static void vop2_update_post_csc_info(struct vop2_video_port *vp,
}
/*
* Check hdr_ext_data switch from valid to NULL or
* NULL to valid.
* This is used to check a switch from dynamic HDR2SDR
* or SDR2HDR output mode switch.
* DOVI will set mode changed at the following case:
* (1) Enter or Exit dovi output mode[judge by old/new crtc state];
* (2) Keep dovi output mode, and change from non dovi video to dovi video[judge
* by core1 bypass_composer state], except dovi_mode changed to non zero value
* by userspace.
*/
static bool vop_hdr_ext_data_switch(struct drm_crtc_state *old_state,
struct drm_crtc_state *new_state)
static bool vop2_dovi_mode_changed(struct drm_crtc *crtc,
struct drm_atomic_state *state)
{
struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_state);
struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_state);
struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state);
struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state);
struct drm_property_blob *new_blob = new_vcstate->hdr_ext_data;
struct drm_property_blob *old_blob = old_vcstate->hdr_ext_data;
struct rockchip_drm_private *private = crtc->dev->dev_private;
struct hdr_extend *old_hdr_data, *new_hdr_data;
bool mode_changed = false;
if ((!old_blob && new_blob) || (!new_blob && old_blob))
return false;
if (!old_blob && new_blob) {
new_hdr_data = (struct hdr_extend *)new_vcstate->hdr_ext_data->data;
if (new_hdr_data->hdr_type == HDR_DOVI)
mode_changed = true;
} else if (!new_blob && old_blob) {
old_hdr_data = (struct hdr_extend *)old_vcstate->hdr_ext_data->data;
if (old_hdr_data->hdr_type == HDR_DOVI)
mode_changed = true;
} else if (old_blob && new_blob) {
struct dovi_regs *old_dovi_reg_data, *new_dovi_reg_data;
return true;
new_hdr_data = (struct hdr_extend *)new_vcstate->hdr_ext_data->data;
old_hdr_data = (struct hdr_extend *)old_vcstate->hdr_ext_data->data;
if (old_hdr_data->hdr_type != new_hdr_data->hdr_type) {
mode_changed = true;
} else if (old_hdr_data->hdr_type == new_hdr_data->hdr_type &&
old_hdr_data->hdr_type == HDR_DOVI &&
+ private->dovi_mode == 0) {
old_dovi_reg_data = &old_hdr_data->dovi_data;
new_dovi_reg_data = &new_hdr_data->dovi_data;
/* dovi core1 bypass_composer change from 1 to 0 must enter mode_changed */
if ((old_dovi_reg_data->core1[1] & BIT(0)) == 1 &&
(new_dovi_reg_data->core1[1] & BIT(0)) == 0) {
mode_changed = true;
DRM_INFO("dovi core1 bypass_composer from 1 to 0\n");
}
}
}
return mode_changed;
}
static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
@@ -10640,7 +10703,6 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
struct rockchip_crtc_state *new_vcstate = to_rockchip_crtc_state(new_crtc_state);
struct rockchip_crtc_state *old_vcstate = to_rockchip_crtc_state(old_crtc_state);
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
bool hdr_ext_data_change;
if (vop2_has_feature(vop2, VOP_FEATURE_SPLICE)) {
if (adjusted_mode->hdisplay > VOP2_MAX_VP_OUTPUT_WIDTH) {
@@ -10665,10 +10727,9 @@ static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
else
vp->acm_state_changed = false;
hdr_ext_data_change = !vop_hdr_ext_data_switch(old_crtc_state, new_crtc_state) |
new_crtc_state->active_changed;
if (hdr_ext_data_change)
new_crtc_state->mode_changed = true;
if (vp_data->feature & VOP_FEATURE_DOVI)
new_crtc_state->mode_changed |=
vop2_dovi_mode_changed(crtc, state);
return 0;
}
@@ -12254,6 +12315,83 @@ static bool post_sharp_enabled(struct drm_crtc *crtc)
return true;
}
static void vop2_crtc_update_zpos_for_dovi(struct drm_crtc *crtc, struct vop2_zpos *vop2_zpos)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
const struct vop2_data *vop2_data = vop2->data;
struct drm_plane *plane;
struct vop2_plane_state *vpstate;
bool has_base_layer = false;
uint8_t nr_layers = 0;
drm_atomic_crtc_for_each_plane(plane, crtc) {
vpstate = to_vop2_plane_state(plane->state);
if (vpstate->dovi_input_type == DOVI_BASE_LAYER)
has_base_layer = true;
}
/*
* At RK3588 force DOVI mode[only have UI->coer2 and none base layer to core1]
* the UI layer must from layer2 and connect to core2, so insert unused win to
* layer0.
*/
if (vp->nr_layers == 1 && has_base_layer == false) {
struct vop2_zpos vop2_zpos0;
int phys_id, freed_phy_id = ROCKCHIP_VOP2_PHY_ID_INVALID;
int zpos0_phy_id = vop2_zpos[0].win_phys_id;
unsigned long win_mask = vp->win_mask;
/* find freed layer to core1 */
for_each_set_bit(phys_id, &win_mask, ROCKCHIP_MAX_LAYER) {
if (phys_id != zpos0_phy_id &&
phys_id != vop2_data->dovi->enhance_layer_phy_id) {
freed_phy_id = phys_id;
break;
}
}
if (freed_phy_id == ROCKCHIP_VOP2_PHY_ID_INVALID) {
DRM_DEV_ERROR(vop2->dev, "Can't find freed phy id for dovi core1\n");
return;
}
memcpy(&vop2_zpos0, &vop2_zpos[0], sizeof(struct vop2_zpos));
vp->nr_layers++;
vop2_zpos[0].zpos = 0;
vop2_zpos[0].win_phys_id = freed_phy_id;
memcpy(&vop2_zpos[1], &vop2_zpos0, sizeof(struct vop2_zpos));
vop2_zpos[1].zpos = 1;
}
nr_layers = vp->nr_layers;
/*
* At RK3588 dovi mode, the layer0 and layer1 is used for dovi layer,
* layer0 for base layer, layer1 for enhance layer, the enhance layer
* is option, but it's always occupy this layer, and the other layer
* must be assigned from layer2, so copy the other layers to &vop_zpos[2].
*/
if (vp->nr_layers > 1) {
struct vop2_zpos *vop2_zpos_tmp;
int i = 0;
vop2_zpos_tmp = kmalloc_array(nr_layers - 1, sizeof(struct vop2_zpos), GFP_KERNEL);
if (!vop2_zpos_tmp)
return;
/* Insert esmart3 as core1 enhance layer to zpos1 */
memcpy(vop2_zpos_tmp, &vop2_zpos[1], (nr_layers - 1) * sizeof(struct vop2_zpos));
vp->nr_layers++;
vop2_zpos[1].zpos = 1;
vop2_zpos[1].win_phys_id = vop2_data->dovi->enhance_layer_phy_id;
memcpy(&vop2_zpos[2], vop2_zpos_tmp, (nr_layers - 1) * sizeof(struct vop2_zpos));
for (i = 0; i < nr_layers - 1; i++)
vop2_zpos[2 + i].zpos = 2 + i;
kfree(vop2_zpos_tmp);
}
}
static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
@@ -12378,33 +12516,9 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_stat
vp->nr_layers = nr_layers;
sort(vop2_zpos, nr_layers, sizeof(vop2_zpos[0]), vop2_zpos_cmp, NULL);
/*
* At RK3588 dovi mode, the layer0 and layer1 is used for dovi layer,
* layer0 for base layer, layer1 for enhance layer, the enhance layer
* is option, but it's always occupy this layer, and the other layer
* must be assigned from layer2, so copy the other layers to &vop_zpos[2].
*/
if (vop2->version == VOP_VERSION_RK3588 &&
vop2_is_dovi_mode(vp) && vp->nr_layers > 1) {
const struct vop2_data *vop2_data = vop2->data;
struct vop2_zpos *vop2_zpos_tmp;
int i = 0;
vop2_zpos_tmp = kmalloc_array(nr_layers - 1, sizeof(struct vop2_zpos), GFP_KERNEL);
if (!vop2_zpos_tmp)
goto dovi_err;
/* Insert esmart3 as core1 enhance layer to zpos1 */
memcpy(vop2_zpos_tmp, &vop2_zpos[1], (nr_layers - 1) * sizeof(struct vop2_zpos));
vp->nr_layers++;
vop2_zpos[1].zpos = 1;
vop2_zpos[1].win_phys_id = vop2_data->dovi->enhance_layer_phy_id;
memcpy(&vop2_zpos[2], vop2_zpos_tmp, (nr_layers - 1) * sizeof(struct vop2_zpos));
for (i = 0; i < nr_layers - 1; i++)
vop2_zpos[2 + i].zpos = 2 + i;
kfree(vop2_zpos_tmp);
}
if (vop2->version == VOP_VERSION_RK3588 && vop2_is_dovi_mode(vp))
vop2_crtc_update_zpos_for_dovi(crtc, vop2_zpos);
if (!vp->hdr10_at_splice_mode) {
if (is_vop3(vop2)) {
@@ -12481,9 +12595,6 @@ static void vop2_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_stat
}
}
dovi_err:
if (vcstate->splice_mode)
kfree(vop2_zpos_splice);
out:
kfree(vop2_zpos);
}
@@ -12894,6 +13005,8 @@ static void vop2_cfg_update(struct drm_crtc *crtc,
if (vp_data->feature & VOP_FEATURE_OVERSCAN)
vop2_post_config(crtc);
if (vp_data->feature & VOP_FEATURE_DOVI)
vop2_dovi_enable(crtc);
if (vop2_is_dovi_mode(vp) && vp->enabled_win_mask) {
vop2_dovi_mode_config(crtc);
vop2_load_dovi_coe_table(crtc);

View File

@@ -520,7 +520,7 @@ struct icm42670_data {
struct regmap *regmap;
struct iio_trigger *trig;
struct device_node *node;
int int1_gpio;
struct gpio_desc *int1_gpiod;
struct regulator *vdd_supply;
struct regulator *vddio_supply;
u16 accel_frequency;

View File

@@ -528,11 +528,10 @@ static int icm42670_gyro_off(struct icm42670_data *data)
return ret;
cmd &= (~(BIT_PWR_MGMT0_GYRO(INV_ICM42670_SENSOR_MODE_LOW_NOISE))); // Gyro off
msleep(80);
ret = regmap_write(data->regmap, REG_PWR_MGMT_0, cmd);
if (ret < 0)
return ret;
msleep(200);
usleep_range(200, 201);
return ret;
}
@@ -1092,10 +1091,6 @@ static int icm42670_chip_init(struct icm42670_data *data, icm42670_bus_setup bus
dev_err(dev, "reset done status bit missing (%0x)\n", regval);
return -ENODEV;
}
// Configure the INT1 GPIO as input
ret = gpio_direction_input(data->int1_gpio);
if (ret < 0)
dev_err(dev, "gpio_direction_input failed!\r\n");
/* set chip bus configuration */
ret = bus_setup(data);
@@ -1224,11 +1219,16 @@ int icm42670_core_probe(struct regmap *regmap,
if (data->node == NULL)
dev_err(dev, "ic2 node not find!\n");
data->int1_gpio = of_get_named_gpio(data->node, "int1-gpio", 0);
if (data->int1_gpio < 0) {
dev_err(dev, "Could not get int1_gpio!\n");
return -EINVAL;
}
data->int1_gpiod = devm_gpiod_get(dev, "int1", GPIOD_IN);
if (IS_ERR(data->int1_gpiod))
return dev_err_probe(dev, PTR_ERR(data->int1_gpiod), "Could not get int1 gpio\n");
/* Get the same result through gpiod_to_irq to ensure that
* the affinity can be restored after CPU off/on
*/
irq = gpiod_to_irq(data->int1_gpiod);
if (irq < 0)
return dev_err_probe(dev, irq, "Could not get IRQ from GPIO\n");
data->enable_fifo = of_property_read_bool(data->node, "enable-fifo");
if (true != data->enable_fifo)
@@ -1338,14 +1338,13 @@ EXPORT_SYMBOL_GPL(icm42670_core_probe);
*/
static int __maybe_unused sleep_icm42670_resume(struct device *dev)
{
int ret;
struct icm42670_data *st = iio_priv(dev_get_drvdata(dev));
int ret = 0;
struct icm42670_data *st = iio_priv(dev_get_drvdata(dev));
struct iio_dev *indio_dev = dev_get_drvdata(dev);
mutex_lock(&st->lock);
ret = regulator_enable(st->vdd_supply);
if (ret)
if (!pm_runtime_suspended(dev))
goto out_unlock;
usleep_range(3000, 4000);
@@ -1360,10 +1359,7 @@ static int __maybe_unused sleep_icm42670_resume(struct device *dev)
icm42670_set_lpf_bw(st, ICM42670_GYRO, st->gyro_lpf_bw_buff);
ret = icm42670_set_enable(indio_dev, 1);
if (ret)
goto out_unlock;
devm_regulator_put(st->vdd_supply);
out_unlock:
mutex_unlock(&st->lock);
return ret;
@@ -1375,28 +1371,21 @@ out_unlock:
*/
static int __maybe_unused sleep_icm42670_suspend(struct device *dev)
{
struct icm42670_data *st = iio_priv(dev_get_drvdata(dev));
struct icm42670_data *st = iio_priv(dev_get_drvdata(dev));
struct iio_dev *indio_dev = dev_get_drvdata(dev);
int ret;
int ret = 0;
mutex_lock(&st->lock);
if (pm_runtime_suspended(dev))
goto out_unlock;
st->gyro_frequency_buff = st->gyro_frequency;
st->accel_frequency_buff = st->accel_frequency;
st->accel_lpf_bw_buff = st->accel_lpf_bw;
st->gyro_lpf_bw_buff = st->gyro_lpf_bw;
if (pm_runtime_suspended(dev)) {
ret = 0;
goto out_unlock;
}
ret = icm42670_set_enable(indio_dev, 0);
if (ret)
goto out_unlock;
regulator_disable(st->vdd_supply);
devm_regulator_put(st->vdd_supply);
out_unlock:
mutex_unlock(&st->lock);

View File

@@ -328,6 +328,7 @@ struct charger_manager {
struct delayed_work cm_monitor_work; /* init at driver add */
struct delayed_work cm_jeita_work; /* init at driver add */
struct delayed_work dc_work;
struct work_struct pd_work;
/* The state of charger cable */
bool attached;
@@ -340,6 +341,7 @@ struct charger_manager {
/* The rockchip-charger-manager use Extcon framework */
struct work_struct wq;
struct notifier_block nb;
struct notifier_block pd_nb;
struct chargepump_info cp;
struct fuel_gauge_info fg_info;
@@ -350,6 +352,9 @@ struct charger_manager {
int is_fast_charge;
int is_charge;
bool is_normal_charge;
bool is_pd_charge;
bool is_pps_charge;
unsigned long next_polling;
u64 charging_start_time;
@@ -695,6 +700,7 @@ static int set_sw_charger_input_limit_current(struct charger_manager *cm,
return ret;
}
cm->fc_config->sw_input_current = input_current_ua;
cm->fc_config->ibus_dcdc_lmt = input_current_ua;
return 0;
}
@@ -2302,6 +2308,7 @@ static int cm_pd_adapter_det(struct charger_manager *cm)
fc_config = cm->fc_config;
cm->is_fast_charge = 1;
cm->is_pd_charge = true;
CM_DBG("POWER_SUPPLY_USB_TYPE_PD\n");
fc_config->charge_type = CHARGE_TYPE_PD;
ret = power_supply_get_property(desc->tcpm_psy,
@@ -2335,12 +2342,15 @@ static int cm_pps_adapter_det(struct charger_manager *cm)
fc_config = cm->fc_config;
cm->is_fast_charge = 1;
cm->is_pps_charge = true;
CM_DBG("POWER_SUPPLY_USB_TYPE_PD_PPS\n");
if (desc->psy_charger_pump_stat != NULL) {
#if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP)
fc_config->charge_type = CHARGE_TYPE_PPS;
CM_DBG("charge_type: %d, %d\n", cm->fc_config->charge_type, __LINE__);
cm_charge_pump_move_state(cm, PPS_PM_STATE_ENTRY);
if (cm->fc_config->jeita_charge_support)
cancel_delayed_work(&cm->cm_jeita_work);
/*
* Setup work for controlling charger
* according to charger cable.
@@ -2399,6 +2409,10 @@ static int cm_normal_adapter_det(struct charger_manager *cm)
fc_config = cm->fc_config;
fc_config->adaper_power_init_flag = 0;
cm->is_normal_charge = false;
cm->is_fast_charge = false;
cm->is_pps_charge = false;
ret = power_supply_get_property(desc->tcpm_psy,
POWER_SUPPLY_PROP_CURRENT_MAX,
&val);
@@ -2548,21 +2562,27 @@ static int charger_extcon_notifier(struct notifier_block *self,
}
switch (val.intval) {
case POWER_SUPPLY_USB_TYPE_PD:
ret = cm_pd_adapter_det(cm);
CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n");
if (ret)
return NOTIFY_BAD;
if (!cm->is_pps_charge && !cm->is_pd_charge) {
ret = cm_pd_adapter_det(cm);
CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n");
if (ret)
return NOTIFY_BAD;
}
break;
case POWER_SUPPLY_USB_TYPE_PD_PPS:
ret = cm_pps_adapter_det(cm);
if (ret)
return NOTIFY_BAD;
CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n");
if (!cm->is_pps_charge) {
ret = cm_pps_adapter_det(cm);
if (ret)
return NOTIFY_BAD;
CM_DBG("USB-TYPE: POWER_SUPPLY_USB_TYPE_PD\n");
}
break;
default:
ret = cm_normal_adapter_det(cm);
if (ret)
return NOTIFY_BAD;
if (!cm->is_pps_charge && !cm->is_pd_charge && !cm->is_normal_charge) {
ret = cm_normal_adapter_det(cm);
if (ret)
return NOTIFY_BAD;
}
break;
}
@@ -2579,6 +2599,94 @@ static int charger_extcon_notifier(struct notifier_block *self,
return NOTIFY_DONE;
}
static void cm_pd_work(struct work_struct *work)
{
struct charger_manager *cm = container_of(work,
struct charger_manager,
pd_work);
struct fastcharge_config *fc_config = cm->fc_config;
struct charger_desc *desc = cm->desc;
union power_supply_propval prop;
int usb_type, online;
int ret;
ret = power_supply_get_property(cm->desc->tcpm_psy,
POWER_SUPPLY_PROP_USB_TYPE, &prop);
if (ret != 0) {
dev_err(cm->dev, "[%d] failed to get POWER_SUPPLY_PROP_ONLINE\n", __LINE__);
return;
}
usb_type = prop.intval;
ret = power_supply_get_property(cm->desc->tcpm_psy,
POWER_SUPPLY_PROP_ONLINE, &prop);
if (ret != 0) {
dev_err(cm->dev, "[%d] failed to get POWER_SUPPLY_PROP_ONLINE\n", __LINE__);
return;
}
online = prop.intval;
if (online) {
cm->attached = 1;
switch (usb_type) {
case POWER_SUPPLY_USB_TYPE_PD_PPS:
CM_DBG("POWER_SUPPLY_USB_TYPE_PD_PPS\n");
if (!cm->is_pps_charge)
cm_pps_adapter_det(cm);
break;
case POWER_SUPPLY_USB_TYPE_PD:
CM_DBG("POWER_SUPPLY_USB_TYPE_PD\n");
power_supply_get_property(desc->tcpm_psy,
POWER_SUPPLY_PROP_CURRENT_MAX,
&prop);
if ((!cm->is_pps_charge && !cm->is_pd_charge) ||
(prop.intval != fc_config->sw_input_current))
cm_pd_adapter_det(cm);
break;
case POWER_SUPPLY_USB_TYPE_C:
CM_DBG("POWER_SUPPLY_USB_TYPE_C\n");
if (!cm->is_pps_charge && !cm->is_pd_charge && !cm->is_normal_charge)
cm_normal_adapter_det(cm);
break;
default:
cm_normal_adapter_det(cm);
}
}
}
static int cm_pd_notifier_call(struct notifier_block *self,
unsigned long event,
void *ptr)
{
struct charger_manager *cm =
container_of(self, struct charger_manager, pd_nb);
struct power_supply *psy = ptr;
if (event != PSY_EVENT_PROP_CHANGED)
return NOTIFY_OK;
if (psy->of_node != cm->desc->tcpm_psy->of_node)
return NOTIFY_OK;
queue_work(cm->cm_wq, &cm->pd_work);
return NOTIFY_OK;
}
static int cm_pd_init(struct charger_manager *cm)
{
int ret;
cm->pd_nb.notifier_call = cm_pd_notifier_call;
ret = power_supply_reg_notifier(&cm->pd_nb);
if (ret) {
dev_err(cm->dev, "failed to power supply reg notifier\n");
return ret;
}
return 0;
}
static void cm_disable_charge(struct charger_manager *cm)
{
#if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP)
@@ -2988,6 +3096,7 @@ static int charger_manager_probe(struct platform_device *pdev)
if (cm->desc->support_dc_charger)
INIT_DELAYED_WORK(&cm->dc_work,
cm_dc_det_work);
INIT_WORK(&cm->pd_work, cm_pd_work);
/* Register extcon device for charger cable */
ret = charger_extcon_init(cm);
@@ -2995,6 +3104,11 @@ static int charger_manager_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "Cannot initialize extcon device\n");
goto err_reg_extcon;
}
ret = cm_pd_init(cm);
if (ret < 0) {
dev_err(&pdev->dev, "Cannot initialize pd device\n");
goto err_reg_extcon;
}
cm_dc_init(cm);
chg_en_create_device_node(&pdev->dev);
@@ -3002,6 +3116,7 @@ static int charger_manager_probe(struct platform_device *pdev)
CM_DBG("charger manager ok!!!");
return 0;
err_reg_extcon:
destroy_workqueue(cm->cm_wq);
return ret;
}
@@ -3035,12 +3150,14 @@ static int charger_manager_remove(struct platform_device *pdev)
{
struct charger_manager *cm = platform_get_drvdata(pdev);
power_supply_unreg_notifier(&cm->pd_nb);
#if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP)
cancel_delayed_work_sync(&cm->cm_monitor_work);
#endif
cancel_delayed_work_sync(&cm->cm_jeita_work);
if (cm->desc->support_dc_charger)
cancel_delayed_work_sync(&cm->dc_work);
destroy_workqueue(cm->cm_wq);
return 0;
}
@@ -3052,11 +3169,13 @@ static void charger_manager_shutdown(struct platform_device *pdev)
union power_supply_propval val;
int ret;
power_supply_unreg_notifier(&cm->pd_nb);
cancel_delayed_work_sync(&cm->cm_monitor_work);
#endif
cancel_delayed_work_sync(&cm->cm_jeita_work);
if (cm->desc->support_dc_charger)
cancel_delayed_work_sync(&cm->dc_work);
destroy_workqueue(cm->cm_wq);
CM_DBG("charger manager shutdown\n");
#if defined(CONFIG_ROCKCHIP_CHARGER_MANAGER_CHARGE_PUMP)