Merge commit '0374714804670f445ac6449d4c0d8b9fbe84590d'

* commit '0374714804670f445ac6449d4c0d8b9fbe84590d':
  power: supply: rk817_battery: Supports battery aging calibration
  power: supply: rk817_battery: Supporting battery charging with JEITA standards‌
  drm/rockchip: vop2: update cluster fbc xoffset check rule
  arm64: dts: rockchip: rk3576: Add customer demand nvmem cell for opp table
  driver: rknpu: Add opp data for rk3576s
  MALI: bifrost: Add opp data for rk3576s
  cpufreq: rockchip: Add opp data for rk3576s
  media: rockchip: isp: support wrap stream latter for isp35
  arm64: dts: rockchip: rv1126b-pinctrl: update i2c config
  arm64: dts: rockchip: rk3588: Adjust the HDMITX1 DDC M0 IO driver strength
  media: rockchip: vicap add soft reset before start stream
  media: rockchip: vicap free hdr buf after change to online
  media: rockchip: vicap fixes error of sof intr loss
  media: rockchip: vicap fixes image error of last frame before suspend
  arm64: dts: rockchip: rv1126b-evb4: add dsmc node
  arm64: dts: rockchip: rv1126b-evb4: enable sdmmc\gmac\can\sound\rtc\fspi
  media: rockchip: vicap support crop with toisp mode
  media: rockchip: vicap fixes error port parse of sditf

Change-Id: If5201f44dd85fe5db2c61357cfac90a8aca743f1
This commit is contained in:
Tao Huang
2025-05-23 18:53:12 +08:00
13 changed files with 965 additions and 199 deletions

View File

@@ -396,8 +396,10 @@
opp-shared;
rockchip,opp-shared-cci;
nvmem-cells = <&cpul_leakage>, <&cpul_opp_info>, <&specification_serial_number>;
nvmem-cell-names = "leakage", "opp-info", "specification_serial_number";
nvmem-cells = <&cpul_leakage>, <&cpul_opp_info>,
<&specification_serial_number>, <&test_version>;
nvmem-cell-names = "leakage", "opp-info",
"specification_serial_number", "test_version";
rockchip,supported-hw;
rockchip,pvtm-hw = <0x06>;
@@ -660,8 +662,10 @@
opp-shared;
rockchip,cpu-freq-percent = <90>;
nvmem-cells = <&cpub_leakage>, <&cpub_opp_info>, <&specification_serial_number>;
nvmem-cell-names = "leakage", "opp-info", "specification_serial_number";
nvmem-cells = <&cpub_leakage>, <&cpub_opp_info>,
<&specification_serial_number>, <&test_version>;
nvmem-cell-names = "leakage", "opp-info",
"specification_serial_number", "test_version";
rockchip,supported-hw;
rockchip,pvtm-hw = <0x06>;
@@ -2444,8 +2448,10 @@
npu_opp_table: npu-opp-table {
compatible = "operating-points-v2";
nvmem-cells = <&npu_leakage>, <&npu_opp_info>, <&specification_serial_number>;
nvmem-cell-names = "leakage", "opp-info", "specification_serial_number";
nvmem-cells = <&npu_leakage>, <&npu_opp_info>,
<&specification_serial_number>, <&test_version>;
nvmem-cell-names = "leakage", "opp-info",
"specification_serial_number", "test_version";
rockchip,supported-hw;
rockchip,pvtm-hw = <0x06>;
@@ -2690,8 +2696,10 @@
gpu_opp_table: gpu-opp-table {
compatible = "operating-points-v2";
nvmem-cells = <&gpu_leakage>, <&gpu_opp_info>, <&specification_serial_number>;
nvmem-cell-names = "leakage", "opp-info", "specification_serial_number";
nvmem-cells = <&gpu_leakage>, <&gpu_opp_info>,
<&specification_serial_number>, <&test_version>;
nvmem-cell-names = "leakage", "opp-info",
"specification_serial_number", "test_version";
rockchip,supported-hw;
rockchip,pvtm-hw = <0x06>;
@@ -4981,6 +4989,10 @@
reg = <0x05 0x1>;
bits = <3 3>;
};
test_version: test-version@7 {
reg = <0x7 0x1>;
bits = <0 4>;
};
specification_serial_number: specification-serial-number@8 {
reg = <0x08 0x1>;
bits = <0 5>;

View File

@@ -160,14 +160,14 @@
hdmim0_tx1_scl: hdmim0-tx1-scl {
rockchip,pins =
/* hdmim0_tx1_scl */
<2 RK_PB5 4 &pcfg_pull_none>;
<2 RK_PB5 4 &pcfg_pull_none_drv_level_3_smt>;
};
/omit-if-no-ref/
hdmim0_tx1_sda: hdmim0-tx1-sda {
rockchip,pins =
/* hdmim0_tx1_sda */
<2 RK_PB4 4 &pcfg_pull_none>;
<2 RK_PB4 4 &pcfg_pull_none_drv_level_1_smt>;
};
};

View File

@@ -26,14 +26,6 @@
reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
};
vcc_mipi: vcc-mipi {
compatible = "regulator-fixed";
regulator-name = "vcc_mipi";
gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
enable-active-high;
regulator-boot-on;
};
vcc5v0_sys: vcc5v0-sys {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_sys";
@@ -71,6 +63,39 @@
pinctrl-0 = <&vcc5v0_host_en>;
};
vcc_mipi: vcc-mipi {
compatible = "regulator-fixed";
regulator-name = "vcc_mipi";
gpio = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
enable-active-high;
regulator-boot-on;
};
vcc_sd: vcc-sd {
compatible = "regulator-fixed";
gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
regulator-name = "vcc_sd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
enable-active-low;
regulator-boot-on; // The legacy U-Boot GPIO driver needs this to set correct SDMMC0_PWREN value
vin-supply = <&vcc12v_dcin>;
};
vccio_sd: vccio-sd {
compatible = "regulator-gpio";
regulator-boot-on;
regulator-name = "vccio_sd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_volt>;
gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
vin-supply = <&vcc5v0_sys>;
states = <1800000 0x0
3300000 0x1>;
};
vdd_npu: vdd-npu {
compatible = "pwm-regulator";
pwms = <&pwm0_8ch_0 0 25000 1>;
@@ -105,10 +130,32 @@
};
};
&acdcdig_dsm {
status = "okay";
pa-ctl-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&dsm_aud_rn_pins &dsm_aud_rp_pins>;
};
&acodec_sound {
status = "okay";
};
&audio_codec {
status = "okay";
};
&backlight {
pwms = <&pwm0_8ch_3 0 25000 0>;
};
&can0 {
assigned-clocks = <&cru CLK_CAN0>;
assigned-clock-rates = <200000000>;
pinctrl-names = "default";
pinctrl-0 = <&can0m1_pins>;
status = "okay";
};
&cpu0 {
cpu-supply = <&vdd_cpu>;
};
@@ -129,6 +176,36 @@
power-supply = <&vcc_mipi>;
};
&dsmc {
clock-frequency = <100000000>;
status = "disabled";
slave {
rockchip,dqs-dll = <0x20 0x20
0x20 0x20
0x20 0x20
0x20 0x20>;
rockchip,ranges = <0x0 0x10000000 0x0 0x2000000>;
};
};
&dsmc_slave {
status = "disabled";
lb-slave {
dsmc_lb_slave0: lb-slave0 {
rockchip,int-en = <0x0>;
status = "okay";
dsmc_p0_region: region {
dsmc_p0_region0: region0 {
status = "okay";
};
dsmc_p0_region3: region3 {
status = "okay";
};
};
};
};
};
&emmc {
bus-width = <8>;
cap-mmc-highspeed;
@@ -140,6 +217,25 @@
status = "okay";
};
&fspi0 {
status = "okay";
flash@0 {
compatible = "spi-nand";
reg = <0>;
spi-max-frequency = <75000000>;
spi-rx-bus-width = <4>;
spi-tx-bus-width = <1>;
};
};
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
phy-handle = <&rmii_phy>;
status = "okay";
};
&i2c0 {
status = "okay";
@@ -267,6 +363,19 @@
};
};
&mdio {
rmii_phy: ethernet-phy@2 {
compatible = "ethernet-phy-id0680.8101", "ethernet-phy-ieee802.3-c22";
reg = <2>;
clocks = <&cru CLK_MACPHY>;
clock-frequency = <50000000>;
resets = <&cru SRST_RESETN_MACPHY>;
pinctrl-names = "default";
pinctrl-0 = <&fephym1_pins>;
phy-is-integrated;
};
};
&mipi_dphy {
status = "okay";
};
@@ -284,6 +393,13 @@
};
};
sdmmc {
/omit-if-no-ref/
sdmmc_volt: sdmmc-volt {
rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
usb {
typec5v_pwren: typec5v-pwren {
rockchip,pins = <5 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -319,10 +435,61 @@
rknpu-supply = <&vdd_npu>;
};
&rockchip_suspend {
status = "okay";
rockchip,sleep-mode-config = <
(0
| RKPM_SLP_ARMOFF_LOGOFF
| RKPM_SLP_PMU_PMUALIVE_32K
| RKPM_SLP_PMU_DIS_OSC
| RKPM_SLP_32K_EXT
)
>;
rockchip,sleep-pin-config = <
(0
| RKPM_SLEEP_PIN2_EN
)
(0
)
>;
};
&route_dsi {
status = "okay";
};
&rtc {
rockchip,rtc-suspend-bypass;
status = "okay";
};
&sai2 {
rockchip,sai-rx-route = <1 0 2 3>;
status = "okay";
/delete-property/ pinctrl-names;
/delete-property/ pinctrl-0;
};
&saradc0 {
vref-supply = <&vcc_1v8>;
};
&sdmmc0 {
max-frequency = <200000000>;
no-sdio;
no-mmc;
bus-width = <4>;
cap-mmc-highspeed;
cap-sd-highspeed;
disable-wp;
sd-uhs-sdr104;
vmmc-supply = <&vcc_sd>;
vqmmc-supply = <&vccio_sd>;
status = "okay";
};
&sdmmc1 {
bus-width = <4>;
cap-sd-highspeed;

View File

@@ -557,18 +557,18 @@
i2c0m0_pins: i2c0m0-pins {
rockchip,pins =
/* i2c0_scl_m0 */
<0 RK_PC2 4 &pcfg_pull_none>,
<0 RK_PC2 4 &pcfg_pull_none_smt>,
/* i2c0_sda_m0 */
<0 RK_PC3 4 &pcfg_pull_none>;
<0 RK_PC3 4 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c0m1_pins: i2c0m1-pins {
rockchip,pins =
/* i2c0_scl_m1 */
<2 RK_PA1 3 &pcfg_pull_none>,
<2 RK_PA1 3 &pcfg_pull_none_smt>,
/* i2c0_sda_m1 */
<2 RK_PA0 3 &pcfg_pull_none>;
<2 RK_PA0 3 &pcfg_pull_none_smt>;
};
};
@@ -577,36 +577,36 @@
i2c1m0_pins: i2c1m0-pins {
rockchip,pins =
/* i2c1_scl_m0 */
<0 RK_PB3 3 &pcfg_pull_none>,
<0 RK_PB3 3 &pcfg_pull_none_smt>,
/* i2c1_sda_m0 */
<0 RK_PB4 3 &pcfg_pull_none>;
<0 RK_PB4 3 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c1m1_pins: i2c1m1-pins {
rockchip,pins =
/* i2c1_scl_m1 */
<3 RK_PA2 2 &pcfg_pull_none>,
<3 RK_PA2 2 &pcfg_pull_none_smt>,
/* i2c1_sda_m1 */
<3 RK_PA3 2 &pcfg_pull_none>;
<3 RK_PA3 2 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c1m2_pins: i2c1m2-pins {
rockchip,pins =
/* i2c1_scl_m2 */
<4 RK_PA1 6 &pcfg_pull_none>,
<4 RK_PA1 6 &pcfg_pull_none_smt>,
/* i2c1_sda_m2 */
<4 RK_PA0 6 &pcfg_pull_none>;
<4 RK_PA0 6 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c1m3_pins: i2c1m3-pins {
rockchip,pins =
/* i2c1_scl_m3 */
<7 RK_PB0 5 &pcfg_pull_none>,
<7 RK_PB0 5 &pcfg_pull_none_smt>,
/* i2c1_sda_m3 */
<7 RK_PB1 5 &pcfg_pull_none>;
<7 RK_PB1 5 &pcfg_pull_none_smt>;
};
};
@@ -615,27 +615,27 @@
i2c2m0_pins: i2c2m0-pins {
rockchip,pins =
/* i2c2_scl_m0 */
<0 RK_PD0 1 &pcfg_pull_none>,
<0 RK_PD0 1 &pcfg_pull_none_smt>,
/* i2c2_sda_m0 */
<0 RK_PD1 1 &pcfg_pull_none>;
<0 RK_PD1 1 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c2m1_pins: i2c2m1-pins {
rockchip,pins =
/* i2c2_scl_m1 */
<5 RK_PD4 6 &pcfg_pull_none>,
<5 RK_PD4 6 &pcfg_pull_none_smt>,
/* i2c2_sda_m1 */
<5 RK_PD5 6 &pcfg_pull_none>;
<5 RK_PD5 6 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c2m2_pins: i2c2m2-pins {
rockchip,pins =
/* i2c2_scl_m2 */
<6 RK_PC0 7 &pcfg_pull_none>,
<6 RK_PC0 7 &pcfg_pull_none_smt>,
/* i2c2_sda_m2 */
<6 RK_PC3 7 &pcfg_pull_none>;
<6 RK_PC3 7 &pcfg_pull_none_smt>;
};
};
@@ -644,36 +644,36 @@
i2c3m0_pins: i2c3m0-pins {
rockchip,pins =
/* i2c3_scl_m0 */
<0 RK_PC0 1 &pcfg_pull_none>,
<0 RK_PC0 1 &pcfg_pull_none_smt>,
/* i2c3_sda_m0 */
<0 RK_PC1 1 &pcfg_pull_none>;
<0 RK_PC1 1 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c3m1_pins: i2c3m1-pins {
rockchip,pins =
/* i2c3_scl_m1 */
<4 RK_PA4 6 &pcfg_pull_none>,
<4 RK_PA4 6 &pcfg_pull_none_smt>,
/* i2c3_sda_m1 */
<4 RK_PA5 6 &pcfg_pull_none>;
<4 RK_PA5 6 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c3m2_pins: i2c3m2-pins {
rockchip,pins =
/* i2c3_scl_m2 */
<5 RK_PD0 6 &pcfg_pull_none>,
<5 RK_PD0 6 &pcfg_pull_none_smt>,
/* i2c3_sda_m2 */
<5 RK_PD1 6 &pcfg_pull_none>;
<5 RK_PD1 6 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c3m3_pins: i2c3m3-pins {
rockchip,pins =
/* i2c3_scl_m3 */
<6 RK_PA0 7 &pcfg_pull_none>,
<6 RK_PA0 7 &pcfg_pull_none_smt>,
/* i2c3_sda_m3 */
<6 RK_PA1 7 &pcfg_pull_none>;
<6 RK_PA1 7 &pcfg_pull_none_smt>;
};
};
@@ -682,36 +682,36 @@
i2c4m0_pins: i2c4m0-pins {
rockchip,pins =
/* i2c4_scl_m0 */
<3 RK_PB4 5 &pcfg_pull_none>,
<3 RK_PB4 5 &pcfg_pull_none_smt>,
/* i2c4_sda_m0 */
<3 RK_PB5 5 &pcfg_pull_none>;
<3 RK_PB5 5 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c4m1_pins: i2c4m1-pins {
rockchip,pins =
/* i2c4_scl_m1 */
<6 RK_PA2 7 &pcfg_pull_none>,
<6 RK_PA2 7 &pcfg_pull_none_smt>,
/* i2c4_sda_m1 */
<6 RK_PA3 7 &pcfg_pull_none>;
<6 RK_PA3 7 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c4m2_pins: i2c4m2-pins {
rockchip,pins =
/* i2c4_scl_m2 */
<4 RK_PA7 6 &pcfg_pull_none>,
<4 RK_PA7 6 &pcfg_pull_none_smt>,
/* i2c4_sda_m2 */
<4 RK_PA6 6 &pcfg_pull_none>;
<4 RK_PA6 6 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c4m3_pins: i2c4m3-pins {
rockchip,pins =
/* i2c4_scl_m3 */
<7 RK_PA1 2 &pcfg_pull_none>,
<7 RK_PA1 2 &pcfg_pull_none_smt>,
/* i2c4_sda_m3 */
<7 RK_PA4 2 &pcfg_pull_none>;
<7 RK_PA4 2 &pcfg_pull_none_smt>;
};
};
@@ -720,36 +720,36 @@
i2c5m0_pins: i2c5m0-pins {
rockchip,pins =
/* i2c5_scl_m0 */
<0 RK_PC4 4 &pcfg_pull_none>,
<0 RK_PC4 4 &pcfg_pull_none_smt>,
/* i2c5_sda_m0 */
<0 RK_PC5 4 &pcfg_pull_none>;
<0 RK_PC5 4 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c5m1_pins: i2c5m1-pins {
rockchip,pins =
/* i2c5_scl_m1 */
<3 RK_PB6 5 &pcfg_pull_none>,
<3 RK_PB6 5 &pcfg_pull_none_smt>,
/* i2c5_sda_m1 */
<3 RK_PB7 5 &pcfg_pull_none>;
<3 RK_PB7 5 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c5m2_pins: i2c5m2-pins {
rockchip,pins =
/* i2c5_scl_m2 */
<5 RK_PA1 2 &pcfg_pull_none>,
<5 RK_PA1 2 &pcfg_pull_none_smt>,
/* i2c5_sda_m2 */
<5 RK_PA7 6 &pcfg_pull_none>;
<5 RK_PA7 6 &pcfg_pull_none_smt>;
};
/omit-if-no-ref/
i2c5m3_pins: i2c5m3-pins {
rockchip,pins =
/* i2c5_scl_m3 */
<6 RK_PA4 7 &pcfg_pull_none>,
<6 RK_PA4 7 &pcfg_pull_none_smt>,
/* i2c5_sda_m3 */
<6 RK_PA5 7 &pcfg_pull_none>;
<6 RK_PA5 7 &pcfg_pull_none_smt>;
};
};

View File

@@ -189,6 +189,58 @@ out:
return ret;
}
static int rk3576_cpu_get_soc_info(struct device *dev, struct device_node *np,
int *bin, int *process)
{
int ret = 0;
u8 spec = 0, test_version = 0;
if (!bin)
return 0;
if (of_property_match_string(np, "nvmem-cell-names",
"specification_serial_number") >= 0) {
ret = rockchip_nvmem_cell_read_u8(np,
"specification_serial_number",
&spec);
if (ret) {
dev_err(dev,
"Failed to get specification_serial_number\n");
return ret;
}
}
if (of_property_match_string(np, "nvmem-cell-names", "test_version") >= 0) {
ret = rockchip_nvmem_cell_read_u8(np, "test_version", &test_version);
if (ret) {
dev_err(dev, "Failed to get test_version\n");
return ret;
}
}
/* RK3576M */
if (spec == 0xd) {
*bin = 1;
/* RK3576J */
} else if (spec == 0xa) {
*bin = 2;
/* RK3576S */
} else if (spec == 0x13) {
if (test_version == 0) {
*bin = 3;
} else {
*bin = 0;
dev_info(dev, "bin=%d (3)\n", *bin);
return 0;
}
}
if (*bin < 0)
*bin = 0;
dev_info(dev, "bin=%d\n", *bin);
return ret;
}
static int rk3576_cpu_set_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
u32 rm)
@@ -416,6 +468,7 @@ static const struct rockchip_opp_data rk3588_cpu_opp_data = {
};
static const struct rockchip_opp_data rk3576_cpu_opp_data = {
.get_soc_info = rk3576_cpu_get_soc_info,
.set_read_margin = rk3576_cpu_set_read_margin,
.set_soc_info = rockchip_opp_set_low_length,
.config_regulators = cpu_opp_config_regulators,
@@ -450,6 +503,10 @@ static const struct of_device_id rockchip_cpufreq_of_match[] = {
.compatible = "rockchip,rk3576",
.data = (void *)&rk3576_cpu_opp_data,
},
{
.compatible = "rockchip,rk3576s",
.data = (void *)&rk3576_cpu_opp_data,
},
{
.compatible = "rockchip,rk3588",
.data = (void *)&rk3588_cpu_opp_data,

View File

@@ -508,6 +508,58 @@ static void kbase_platform_rk_remove_sysfs_files(struct device *dev)
device_remove_file(dev, &dev_attr_utilisation);
}
static int rk3576_gpu_get_soc_info(struct device *dev, struct device_node *np,
int *bin, int *process)
{
int ret = 0;
u8 spec = 0, test_version = 0;
if (!bin)
return 0;
if (of_property_match_string(np, "nvmem-cell-names",
"specification_serial_number") >= 0) {
ret = rockchip_nvmem_cell_read_u8(np,
"specification_serial_number",
&spec);
if (ret) {
dev_err(dev,
"Failed to get specification_serial_number\n");
return ret;
}
}
if (of_property_match_string(np, "nvmem-cell-names", "test_version") >= 0) {
ret = rockchip_nvmem_cell_read_u8(np, "test_version", &test_version);
if (ret) {
dev_err(dev, "Failed to get test_version\n");
return ret;
}
}
/* RK3576M */
if (spec == 0xd) {
*bin = 1;
/* RK3576J */
} else if (spec == 0xa) {
*bin = 2;
/* RK3576S */
} else if (spec == 0x13) {
if (test_version == 0) {
*bin = 3;
} else {
*bin = 0;
dev_info(dev, "bin=%d (3)\n", *bin);
return 0;
}
}
if (*bin < 0)
*bin = 0;
dev_info(dev, "bin=%d\n", *bin);
return ret;
}
static int rk3576_gpu_set_read_margin(struct device *dev,
struct rockchip_opp_info *opp_info,
u32 rm)
@@ -648,6 +700,7 @@ static int gpu_opp_config_clks(struct device *dev, struct opp_table *opp_table,
}
static const struct rockchip_opp_data rk3576_gpu_opp_data = {
.get_soc_info = rk3576_gpu_get_soc_info,
.set_read_margin = rk3576_gpu_set_read_margin,
.set_soc_info = rockchip_opp_set_low_length,
.config_regulators = gpu_opp_config_regulators,
@@ -671,6 +724,10 @@ static const struct of_device_id rockchip_mali_of_match[] = {
.compatible = "rockchip,rk3576",
.data = (void *)&rk3576_gpu_opp_data,
},
{
.compatible = "rockchip,rk3576s",
.data = (void *)&rk3576_gpu_opp_data,
},
{
.compatible = "rockchip,rk3588",
.data = (void *)&rk3588_gpu_opp_data,

View File

@@ -5856,6 +5856,8 @@ static int vop2_cluster_two_win_mode_check(struct drm_plane_state *pstate)
struct vop2_win *main_win = vop2_find_win_by_phys_id(vop2, win->phys_id);
struct drm_plane_state *main_pstate;
int actual_w = drm_rect_width(&pstate->src) >> 16;
struct drm_framebuffer *fb = pstate->fb;
u8 block_w = IS_ROCKCHIP_RFBC_MOD(fb->modifier) ? 64 : fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 ? 32 : 16;
int xoffset;
if (pstate->fb->modifier == DRM_FORMAT_MOD_LINEAR)
@@ -5890,9 +5892,9 @@ static int vop2_cluster_two_win_mode_check(struct drm_plane_state *pstate)
xoffset = main_pstate->src.x1 >> 16;
actual_w = drm_rect_width(&main_pstate->src) >> 16;
if ((actual_w + xoffset % 16) > 2048) {
DRM_ERROR("%s act_w(%d) + xoffset(%d) / 16 << 2048 in two win mode\n",
main_win->name, actual_w, xoffset);
if ((actual_w + xoffset % block_w) > 2048) {
DRM_ERROR("%s act_w(%d) + xoffset(%d) %% %d > 2048 in two win mode\n",
main_win->name, actual_w, xoffset, block_w);
return -EINVAL;
}

View File

@@ -4822,6 +4822,7 @@ static int rkcif_csi_channel_set_v1(struct rkcif_stream *stream,
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
CSI_ALL_ERROR_INTEN_V1);
rkcif_do_soft_reset(dev);
}
#if IS_ENABLED(CONFIG_CPU_RV1106)
if (channel->id == 1)
@@ -5094,6 +5095,7 @@ static int rkcif_csi_channel_set_rv1126b(struct rkcif_stream *stream,
rkcif_write_register_or(dev, CIF_REG_MIPI_LVDS_INTEN,
CSI_ALL_ERROR_INTEN_V1);
rkcif_do_soft_reset(dev);
}
if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
@@ -9015,6 +9017,7 @@ void rkcif_stream_init(struct rkcif_device *dev, u32 id)
stream->frame_idx = 0;
memset(&stream->sensor_exp_info, 0, sizeof(stream->sensor_exp_info));
stream->frame_loss = 0;
stream->is_pause_stream = false;
}
int rkcif_sensor_set_power(struct rkcif_stream *stream, int on)
@@ -11736,27 +11739,6 @@ static void rkcif_store_last_buf_for_online(struct rkcif_stream *stream,
buf->dummy.dma_addr);
}
static void rkcif_release_unnecessary_buf_for_online(struct rkcif_stream *stream,
struct rkcif_rx_buffer *buf)
{
struct rkcif_device *dev = stream->cifdev;
struct sditf_priv *priv = dev->sditf[0];
struct rkcif_rx_buffer *rx_buf = NULL;
unsigned long flags;
int i = 0;
spin_lock_irqsave(&priv->cif_dev->buffree_lock, flags);
for (i = 0; i < priv->buf_num; i++) {
rx_buf = &stream->rx_buf[i];
if (rx_buf && (!rx_buf->dummy.is_free) && rx_buf != buf) {
list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
stream->total_buf_num--;
}
}
spin_unlock_irqrestore(&priv->cif_dev->buffree_lock, flags);
schedule_work(&priv->buffree_work.work);
}
static void rkcif_line_wake_up_rdbk(struct rkcif_stream *stream, int mipi_id)
{
u32 mode;
@@ -11819,7 +11801,6 @@ static void rkcif_line_wake_up_rdbk(struct rkcif_stream *stream, int mipi_id)
stream->cur_stream_mode &= ~RKCIF_STREAM_MODE_TOISP_RDBK;
stream->cur_stream_mode |= RKCIF_STREAM_MODE_TOISP;
stream->cifdev->wait_line = 0;
stream->is_line_wake_up = false;
v4l2_dbg(3, rkcif_debug, &stream->cifdev->v4l2_dev,
"stream[%d] frame_idx %d, last_rx_buf_idx %d cur dma buf %x, change to online\n",
stream->id, stream->frame_idx, stream->last_rx_buf_idx,
@@ -13060,10 +13041,13 @@ void rkcif_enable_dma_capture(struct rkcif_stream *stream, bool is_only_enable)
} else {
val |= CSI_DMA_ENABLE_RK3576;
uncompact = CSI_WRDDR_TYPE_RAW_UNCOMPACT << 3;
rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT,
CSI_START_INTSTAT_RK3576(stream->id));
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_INTEN,
CSI_START_INTEN_RK3576(stream->id));
if (!(rkcif_read_register(cif_dev, CIF_REG_MIPI_LVDS_INTEN) &
CSI_START_INTEN_RK3576(stream->id))) {
rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT,
CSI_START_INTSTAT_RK3576(stream->id));
rkcif_write_register_or(cif_dev, CIF_REG_MIPI_LVDS_INTEN,
CSI_START_INTEN_RK3576(stream->id));
}
}
if (!stream->is_compact)
val |= uncompact;
@@ -13651,6 +13635,7 @@ static void rkcif_toisp_check_stop_status(struct sditf_priv *priv,
rkcif_stop_dma_capture(stream);
}
stream->is_wait_stop_complete = false;
stream->is_pause_stream = true;
complete(&stream->stop_complete);
}
if (stream->cifdev->sensor_state_change &&
@@ -15023,6 +15008,7 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
if (stream->is_finish_stop_dma && stream->is_wait_stop_complete) {
stream->is_wait_stop_complete = false;
stream->is_pause_stream = true;
complete(&stream->stop_complete);
}
@@ -15121,11 +15107,9 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
rkcif_modify_frame_skip_config(stream);
if (stream->is_change_toisp) {
stream->is_change_toisp = false;
if ((cif_dev->hdr.hdr_mode == HDR_X2 && stream->id != 1) ||
(cif_dev->hdr.hdr_mode == HDR_X3 && stream->id != 2))
rkcif_release_unnecessary_buf_for_online(stream,
stream->curr_buf_toisp);
else
if (cif_dev->hdr.hdr_mode == NO_HDR ||
(cif_dev->hdr.hdr_mode == HDR_X2 && stream->id == 1) ||
(cif_dev->hdr.hdr_mode == HDR_X3 && stream->id == 2))
sditf_change_to_online(cif_dev->sditf[0]);
rkcif_modify_line_int(stream, false);
stream->is_line_inten = false;
@@ -15168,8 +15152,11 @@ void rkcif_irq_pingpong_v1(struct rkcif_device *cif_dev)
}
if (stream->to_stop_dma) {
ret = rkcif_stop_dma_capture(stream);
if (!ret)
if (!ret) {
stream->is_finish_stop_dma = true;
if (stream->is_wait_stop_complete)
stream->is_pause_stream = true;
}
}
spin_unlock_irqrestore(&stream->vbq_lock, flags);

View File

@@ -670,6 +670,7 @@ struct rkcif_stream {
bool is_wait_single_cap;
bool is_m_online_fb_res;
bool is_fb_first_frame;
bool is_pause_stream;
};
struct rkcif_lvds_subdev {

View File

@@ -201,6 +201,11 @@ static int sditf_get_set_fmt(struct v4l2_subdev *sd,
if (!ret) {
fmt->format.width = input_sel.r.width;
fmt->format.height = input_sel.r.height;
priv->cap_info.offset_x = input_sel.r.left;
priv->cap_info.offset_y = input_sel.r.top;
} else {
priv->cap_info.offset_x = 0;
priv->cap_info .offset_y = 0;
}
priv->cap_info.width = fmt->format.width;
priv->cap_info.height = fmt->format.height;
@@ -732,8 +737,8 @@ static int sditf_channel_enable_rv1103b(struct sditf_priv *priv, int user)
unsigned int ctrl_ch1 = 0;
unsigned int ctrl_ch2 = 0;
unsigned int int_en = 0;
unsigned int offset_x = 0;
unsigned int offset_y = 0;
unsigned int offset_x = priv->cap_info.offset_x;
unsigned int offset_y = priv->cap_info.offset_y;
unsigned int width = priv->cap_info.width;
unsigned int height = priv->cap_info.height;
int csi_idx = cif_dev->csi_host_idx;
@@ -1016,10 +1021,36 @@ static void sditf_channel_disable_rv1103b(struct sditf_priv *priv, int user)
rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CH2_CTRL, ~ctrl_val);
}
static void rkcif_release_unnecessary_buf_for_online(struct rkcif_stream *stream,
struct rkcif_rx_buffer *buf)
{
struct rkcif_device *dev = stream->cifdev;
struct sditf_priv *priv = dev->sditf[0];
struct rkcif_rx_buffer *rx_buf = NULL;
unsigned long flags;
int i = 0;
if (!buf)
buf = stream->last_buf_toisp;
spin_lock_irqsave(&priv->cif_dev->buffree_lock, flags);
for (i = 0; i < stream->rx_buf_num; i++) {
rx_buf = &stream->rx_buf[i];
if (rx_buf && (!rx_buf->dummy.is_free) && rx_buf != buf) {
list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
stream->total_buf_num--;
atomic_dec(&stream->buf_cnt);
}
}
spin_unlock_irqrestore(&priv->cif_dev->buffree_lock, flags);
schedule_work(&priv->buffree_work.work);
}
void sditf_change_to_online(struct sditf_priv *priv)
{
struct rkcif_device *cif_dev = priv->cif_dev;
struct rkcif_stream *cur_stream = NULL;
int i = 0;
int stream_cnt = 0;
priv->mode = priv->mode_src;
if (priv->mode.rdbk_mode != RKISP_VICAP_ONLINE_UNITE &&
@@ -1027,18 +1058,21 @@ void sditf_change_to_online(struct sditf_priv *priv)
sditf_enable_immediately(priv);
if (cif_dev->is_thunderboot) {
if (priv->hdr_cfg.hdr_mode == NO_HDR) {
cur_stream = &cif_dev->stream[0];
cif_dev->stream[0].is_line_wake_up = false;
} else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
if (priv->hdr_cfg.hdr_mode == HDR_X2) {
cur_stream = &cif_dev->stream[1];
cif_dev->stream[0].is_line_wake_up = false;
cif_dev->stream[1].is_line_wake_up = false;
stream_cnt = 1;
} else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
cur_stream = &cif_dev->stream[2];
cif_dev->stream[0].is_line_wake_up = false;
cif_dev->stream[1].is_line_wake_up = false;
cif_dev->stream[2].is_line_wake_up = false;
stream_cnt = 2;
} else {
cur_stream = &cif_dev->stream[0];
cif_dev->stream[0].is_line_wake_up = false;
stream_cnt = 0;
}
if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE_UNITE)
@@ -1052,6 +1086,9 @@ void sditf_change_to_online(struct sditf_priv *priv)
if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE_UNITE)
rkcif_reinit_right_half_config(cur_stream);
for (i = 0; i < stream_cnt; i++)
rkcif_release_unnecessary_buf_for_online(&cif_dev->stream[i],
cif_dev->stream[i].curr_buf_toisp);
}
}
@@ -1316,7 +1353,8 @@ static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
if (!is_free && (!dbufs->is_switch) && stream->state == RKCIF_STATE_STREAMING) {
list_add_tail(&rx_buf->list, &stream->rx_buf_head);
rkcif_assign_check_buffer_update_toisp(stream);
if (cif_dev->resume_mode != RKISP_RTT_MODE_ONE_FRAME) {
if (cif_dev->resume_mode != RKISP_RTT_MODE_ONE_FRAME &&
(!stream->is_pause_stream)) {
if (!stream->dma_en) {
stream->to_en_dma = RKCIF_DMAEN_BY_ISP;
rkcif_enable_dma_capture(stream, true);
@@ -1501,8 +1539,8 @@ static int sditf_fwnode_parse(struct device *dev,
struct v4l2_mbus_config *config = &s_asd->mbus;
if (vep->base.port != 0) {
dev_err(dev, "sditf has only port 0\n");
return -EINVAL;
dev_info(dev, "sditf has only parse port 0\n");
return 0;
}
if (vep->bus_type == V4L2_MBUS_CSI2_DPHY ||

View File

@@ -530,6 +530,11 @@ static int mp_config_mi(struct rkisp_stream *stream)
if (dev->cap_dev.wrap_line) {
height = dev->cap_dev.wrap_line;
rkisp_unite_clear_bits(dev, ISP32_MI_WR_WRAP_CTRL, BIT(0), false);
val = ISP33_SW_ISP2ENC_PATH_EN;
if (IS_HDR_RDBK(dev->hdr.op_mode))
val |= ISP33_PP_ENC_PIPE_EN;
rkisp_unite_set_bits(dev, CTRL_SWS_CFG, 0, val, false);
}
val = out_fmt->plane_fmt[0].bytesperline;
if (fmt->fmt_type != FMT_TILE)

View File

@@ -73,6 +73,16 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
#define ADC_TO_CAPACITY_MAH(adc_value, samp_res) \
(adc_value / 1000 * 1720 / 3600 / samp_res)
/* Adjust full capacity to a reduced value */
#define UPDATE_REDUCE_FCC(fcc) ((fcc) * 995 / 1000)
/* Raise the maximum capacity value */
#define UPDATE_RAISE_FCC(fcc) ((fcc) * 1005 / 1000)
/* Effective full capacity */
#define EFFECTIVE_FULL_MIN_CAP(fcc) ((fcc) * 800 / 1000)
#define EFFECTIVE_FULL_MAX_CAP(fcc) ((fcc) * 1200 / 1000)
/* Battery Percentage (or State of Charge (SOC) Percentage) */
#define BATTERY_PERCENTAGE(n) (n * 1000)
#define ADC_CALIB_THRESHOLD 4
#define ADC_CALIB_LMT_MIN 3
#define ADC_CALIB_CNT 5
@@ -84,16 +94,6 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
#define DEFAULT_SLP_FILTER_CUR 100
#define DEFAULT_PWROFF_VOL_THRESD 3400
#define DEFAULT_MONITOR_SEC 5
#define DEFAULT_ALGR_VOL_THRESD1 3850
#define DEFAULT_ALGR_VOL_THRESD2 3950
#define DEFAULT_CHRG_VOL_SEL CHRG_VOL4200MV
#define DEFAULT_CHRG_CUR_SEL CHRG_CUR1400MA
#define DEFAULT_CHRG_CUR_INPUT INPUT_CUR2000MA
#define DEFAULT_POFFSET 42
#define DEFAULT_MAX_SOC_OFFSET 60
#define DEFAULT_FB_TEMP TEMP_115C
#define DEFAULT_ENERGY_MODE 0
#define DEFAULT_ZERO_RESERVE_DSOC 10
#define DEFAULT_SAMPLE_RES 20
/* sleep */
@@ -128,6 +128,40 @@ module_param_named(dbg_level, dbg_enable, int, 0644);
/* OCV Table Percentage Accuracy: 5.000% */
#define OCV_TABLE_STEP 5000
enum ts_fun {
TS_FUN_SOURCE_CURRENT,
TS_FUN_VOLTAGE_INPUT,
};
enum tscur_sel {
FLOW_OUT_10uA,
FLOW_OUT_20uA,
FLOW_OUT_30uA,
FLOW_OUT_40uA,
};
enum charge_current {
CHRG_CUR_1000MA,
CHRG_CUR_1500MA,
CHRG_CUR_2000MA,
CHRG_CUR_2500MA,
CHRG_CUR_2750MA,
CHRG_CUR_3000MA,
CHRG_CUR_3500MA,
CHRG_CUR_500MA,
};
enum charge_voltage {
CHRG_VOL_4100MV,
CHRG_VOL_4150MV,
CHRG_VOL_4200MV,
CHRG_VOL_4250MV,
CHRG_VOL_4300MV,
CHRG_VOL_4350MV,
CHRG_VOL_4400MV,
CHRG_VOL_4450MV,
};
enum work_mode {
MODE_ZERO = 0,
MODE_FINISH,
@@ -214,12 +248,12 @@ enum rk817_battery_fields {
REMAIN_CAP_REG2, REMAIN_CAP_REG1, REMAIN_CAP_REG0,
NEW_FCC_REG2, NEW_FCC_REG1, NEW_FCC_REG0,
RESET_MODE,
FG_INIT, HALT_CNT_REG, CALC_REST_REGL, CALC_REST_REGH,
FG_INIT, HALT_CNT_REG, CALC_REST_REGL, UPDATE_LEVE_REG,
VOL_ADC_B3, VOL_ADC_B2, VOL_ADC_B1, VOL_ADC_B0,
VOL_ADC_K3, VOL_ADC_K2, VOL_ADC_K1, VOL_ADC_K0,
BAT_EXS, CHG_STS, BAT_OVP_STS, CHRG_IN_CLAMP,
CHIP_NAME_H, CHIP_NAME_L,
PLUG_IN_STS,
CHIP_NAME_H, CHIP_NAME_L, CHRG_CUR_SEL, CHRG_VOL_SEL,
PLUG_IN_STS, BAT_LTS_TS, USB_SYS_EN,
F_MAX_FIELDS
};
@@ -370,7 +404,7 @@ static const struct reg_field rk817_battery_reg_fields[] = {
[HALT_CNT_REG] = REG_FIELD(0xA6, 0, 7),
[CALC_REST_REGL] = REG_FIELD(0xA7, 0, 7),
[CALC_REST_REGH] = REG_FIELD(0xA8, 0, 7),
[UPDATE_LEVE_REG] = REG_FIELD(0xA8, 0, 7),
[VOL_ADC_B3] = REG_FIELD(0xA9, 0, 7),
[VOL_ADC_B2] = REG_FIELD(0xAA, 0, 7),
@@ -381,6 +415,10 @@ static const struct reg_field rk817_battery_reg_fields[] = {
[VOL_ADC_K2] = REG_FIELD(0xAE, 0, 7),
[VOL_ADC_K1] = REG_FIELD(0xAF, 0, 7),
[VOL_ADC_K0] = REG_FIELD(0xB0, 0, 7),
[CHRG_CUR_SEL] = REG_FIELD(0xE4, 0, 2),
[CHRG_VOL_SEL] = REG_FIELD(0xE4, 4, 6),
[USB_SYS_EN] = REG_FIELD(0xE6, 6, 6),
[BAT_LTS_TS] = REG_FIELD(0xE9, 0, 7),
[BAT_EXS] = REG_FIELD(0xEB, 7, 7),
[CHG_STS] = REG_FIELD(0xEB, 4, 6),
[BAT_OVP_STS] = REG_FIELD(0xEB, 3, 3),
@@ -390,10 +428,24 @@ static const struct reg_field rk817_battery_reg_fields[] = {
[PLUG_IN_STS] = REG_FIELD(0xF0, 6, 6),
};
struct temp_chrg_table {
int temp_down;
int temp_up;
int chrg_current;
int chrg_voltage;
int chrg_current_index;
int chrg_voltage_index;
};
struct battery_platform_data {
u32 *ocv_table;
u32 ocv_size;
struct temp_chrg_table *tc_table;
u32 tc_count;
u32 *ntc_table;
u32 ntc_size;
int ntc_degree_from;
u32 ntc_factor;
u32 pwroff_vol;
u32 monitor_sec;
u32 bat_res;
@@ -403,7 +455,6 @@ struct battery_platform_data {
u32 sleep_exit_current;
u32 sleep_filter_current;
u32 max_soc_offset;
u32 bat_mode;
u32 sample_res;
u32 bat_res_up;
@@ -487,7 +538,7 @@ struct rk817_battery_device {
bool is_force_calib;
int ocv_pre_dsoc;
int ocv_new_dsoc;
int charge_index;
int force_pre_dsoc;
int force_new_dsoc;
@@ -523,6 +574,11 @@ static unsigned long base2sec(unsigned long x)
return 0;
}
static unsigned long base2min(unsigned long x)
{
return base2sec(x) / 60;
}
static u32 interpolate(int value, u32 *table, int size)
{
u8 i;
@@ -680,6 +736,16 @@ static void rk817_bat_init_voltage_kb(struct rk817_battery_device *battery)
}
}
static void rk817_bat_save_age_level(struct rk817_battery_device *battery, u8 level)
{
rk817_bat_field_write(battery, UPDATE_LEVE_REG, level);
}
static u8 rk817_bat_get_age_level(struct rk817_battery_device *battery)
{
return rk817_bat_field_read(battery, UPDATE_LEVE_REG);
}
static void rk817_bat_restart_relax(struct rk817_battery_device *battery)
{
rk817_bat_field_write(battery, RELAX_VOL1_UPD, 0x00);
@@ -766,14 +832,6 @@ static void rk817_bat_set_relax_sample(struct rk817_battery_device *battery)
__func__, pdata->sleep_enter_current, pdata->sleep_exit_current);
}
/* runtime OCV voltage, |RLX_VOL2 - RLX_VOL1| < OCV_THRE,
* the OCV reg update every 120s
*/
static void rk817_bat_ocv_thre(struct rk817_battery_device *battery, int value)
{
rk817_bat_field_write(battery, OCV_THRE_VOL, value);
}
static int rk817_bat_get_ocv_voltage(struct rk817_battery_device *battery)
{
int vol, val = 0, vol_temp;
@@ -1100,7 +1158,7 @@ static void rk817_bat_update_qmax(struct rk817_battery_device *battery,
rk817_bat_field_write(battery, Q_MAX_L1, buf);
buf = (cap_adc >> 0) & 0xff;
rk817_bat_field_write(battery, Q_MAX_L0, buf);
battery->qmax = capacity;
battery->qmax = capacity;
}
static int rk817_bat_get_qmax(struct rk817_battery_device *battery)
@@ -1305,6 +1363,210 @@ static int rk817_bat_get_charge_status(struct rk817_battery_device *battery)
return status;
}
static void rk817_bat_update_fcc(struct rk817_battery_device *battery)
{
static int update_status;
int temp_fcc = 0;
if (update_status)
return;
/* The conditions to update FCC are:
* during discharging state,
* with temperature above 18°C and
* displayed battery level below 1%
*/
if ((battery->chrg_status != CHRG_OFF) || (battery->dsoc > 1000) ||
(battery->temperature < VIRTUAL_TEMPERATURE))
return;
/*
* Update the FCC to 99.5% of its original value when the aforementioned
* basic conditions are met and the loaded voltage falls below
* the DTS-configured shutdown voltage.
*/
if ((battery->voltage_avg <= battery->pdata->pwroff_vol) &&
(battery->rsoc > BATTERY_PERCENTAGE(1))) {
temp_fcc = UPDATE_REDUCE_FCC(battery->fcc);
if (temp_fcc > EFFECTIVE_FULL_MIN_CAP(battery->pdata->design_capacity)) {
DBG("REDUCE: update fcc: design: %d, old: %d, new: %d\n",
battery->pdata->design_capacity, battery->fcc, temp_fcc);
battery->qmax = temp_fcc;
battery->fcc = temp_fcc;
rk817_bat_update_qmax(battery, battery->qmax);
rk817_bat_save_fcc(battery, battery->fcc);
update_status = 1;
}
}
/* Update the FCC to 100.5% of its original value when the following conditions are met:
*
* The aforementioned basic conditions are satisfied
* (e.g., discharging state, temperature >18°C).
* The loaded voltage exceeds the voltage corresponding to 5% SOC in the OCV table.
* The RSOC (Relative State of Charge) is below 5%.
*/
if ((battery->voltage_avg >= battery->pdata->ocv_table[1]) &&
(battery->rsoc < BATTERY_PERCENTAGE(5))) {
temp_fcc = UPDATE_RAISE_FCC(battery->fcc);
if (temp_fcc < EFFECTIVE_FULL_MAX_CAP(battery->pdata->design_capacity)) {
DBG("RAISE fcc: design: %d, old: %d, new: %d\n",
battery->pdata->design_capacity, battery->fcc, temp_fcc);
battery->qmax = temp_fcc;
battery->fcc = temp_fcc;
rk817_bat_update_qmax(battery, battery->qmax);
rk817_bat_save_fcc(battery, battery->fcc);
update_status = 1;
}
}
}
static void rk817_bat_enable_usb2vsys(struct rk817_battery_device *battery)
{
DBG("enable usb2vsys!!!\n");
rk817_bat_field_write(battery, USB_SYS_EN, 1);
}
static void rk817_bat_disable_usb2vsys(struct rk817_battery_device *battery)
{
DBG("disable usb2vsys!!!\n");
rk817_bat_field_write(battery, USB_SYS_EN, 0);
}
static void rk817_bat_enable_charge(struct rk817_battery_device *battery)
{
DBG("enable charge by BAT_LTS_TS: 0xFA\n");
rk817_bat_field_write(battery, BAT_LTS_TS, 0xFA);
}
static void rk817_bat_disable_charge(struct rk817_battery_device *battery)
{
DBG("disable charge by BAT_LTS_TS: 0x05\n");
rk817_bat_field_write(battery, BAT_LTS_TS, 0x05);
}
static void rk817_bat_init_ts_detect(struct rk817_battery_device *battery)
{
if (!battery->pdata->ntc_size)
return;
/* the adc of ts1 controlled bit: enable */
rk817_bat_field_write(battery, TS_ADC_EN, ENABLE);
/* source current to TS pin */
rk817_bat_field_write(battery, TS_FUN, TS_FUN_SOURCE_CURRENT);
/* ts pin flow out current in active state */
rk817_bat_field_write(battery, VOL_ADC_TSCUR_SEL, FLOW_OUT_20uA);
battery->pdata->ntc_factor = (FLOW_OUT_20uA + 1) * 10;
rk817_bat_enable_charge(battery);
}
static void rk817_bat_temperature_chrg(struct rk817_battery_device *battery, int temp)
{
int i, up_temp, down_temp;
int now_temp = temp;
for (i = 0; i < battery->pdata->tc_count; i++) {
up_temp = battery->pdata->tc_table[i].temp_up;
down_temp = battery->pdata->tc_table[i].temp_down;
if (now_temp >= down_temp && now_temp <= up_temp) {
/* Temp range or charger are not update, return */
if (battery->charge_index == i)
return;
if ((battery->pdata->tc_table[i].chrg_current != 0) &&
(battery->pdata->tc_table[i].chrg_current_index != 0xff)) {
rk817_bat_field_write(battery,
CHRG_CUR_SEL,
battery->pdata->tc_table[i].chrg_current_index);
DBG("T change: charger current: %d, index: %d\n",
battery->pdata->tc_table[i].chrg_current,
battery->pdata->tc_table[i].chrg_current_index);
} else
rk817_bat_disable_charge(battery);
if ((battery->pdata->tc_table[i].chrg_voltage != 0) &&
(battery->pdata->tc_table[i].chrg_voltage_index != 0xff)) {
rk817_bat_disable_usb2vsys(battery);
rk817_bat_field_write(battery,
CHRG_VOL_SEL,
battery->pdata->tc_table[i].chrg_voltage_index);
rk817_bat_enable_usb2vsys(battery);
DBG("T change: charger voltage: %d, index: %d\n",
battery->pdata->tc_table[i].chrg_voltage,
battery->pdata->tc_table[i].chrg_voltage_index);
} else
rk817_bat_enable_charge(battery);
battery->charge_index = i;
}
}
}
static int rk817_bat_get_bat_ts(struct rk817_battery_device *battery)
{
int temp_value = 0;
temp_value = rk817_bat_field_read(battery, BAT_TS_H) << 8;
temp_value |= rk817_bat_field_read(battery, BAT_TS_L);
return temp_value;
}
static int rk817_bat_get_nts_res(struct rk817_battery_device *battery)
{
int temp_value, res;
int adc_to_vol;
temp_value = rk817_bat_get_bat_ts(battery);
adc_to_vol = temp_value * 1200 / 65536;
res = adc_to_vol * 1000 / battery->pdata->ntc_factor;
DBG("NTC: ADC: value: 0x%x, adc2vol:%d, res: %d\n",
temp_value, adc_to_vol, res);
return res;
}
static void rk817_bat_update_temperature(struct rk817_battery_device *battery)
{
u32 ntc_size, *ntc_table;
int i, res;
ntc_table = battery->pdata->ntc_table;
ntc_size = battery->pdata->ntc_size;
if (ntc_size) {
res = rk817_bat_get_nts_res(battery);
if (res == 0)
return;
if (res < ntc_table[ntc_size - 1]) {
battery->temperature = (ntc_size + battery->pdata->ntc_degree_from) * 10;
DBG("bat ntc upper max degree: R=%d\n", res);
} else if (res > ntc_table[0]) {
battery->temperature = battery->pdata->ntc_degree_from * 10;
DBG("bat ntc lower min degree: R=%d\n", res);
} else {
for (i = 0; i < ntc_size; i++) {
if (res >= ntc_table[i])
break;
}
if (i <= 0)
battery->temperature =
(battery->pdata->ntc_degree_from) * 10;
else
battery->temperature =
(i + battery->pdata->ntc_degree_from) * 10;
}
DBG("Temperature: %d\n", battery->temperature);
rk817_bat_temperature_chrg(battery, battery->temperature / 10);
}
}
/*
* cccv and finish switch all the time will cause dsoc freeze,
* if so, do finish chrg, 100ma is less than min finish_ma.
@@ -1523,7 +1785,7 @@ static void rk817_bat_first_pwron(struct rk817_battery_device *battery)
static void rk817_bat_not_first_pwron(struct rk817_battery_device *battery)
{
int now_cap, pre_soc, pre_cap, ocv_cap, ocv_soc, ocv_vol;
int now_cap, pre_soc, pre_cap;
battery->fcc = rk817_bat_get_fcc(battery);
pre_soc = rk817_bat_get_prev_dsoc(battery);
@@ -1543,43 +1805,11 @@ static void rk817_bat_not_first_pwron(struct rk817_battery_device *battery)
rk817_bat_init_coulomb_cap(battery, now_cap);
pre_cap = now_cap;
pre_soc = battery->rsoc;
goto finish;
} else if (battery->is_initialized) {
/* uboot initialized */
BAT_INFO("initialized yet..\n");
goto finish;
} else if (battery->is_ocv_calib) {
/* not initialized and poweroff_cnt above 30 min */
ocv_vol = rk817_bat_get_ocv_voltage(battery);
ocv_soc = rk817_bat_vol2soc(battery, ocv_vol);
ocv_cap = rk817_bat_vol2cap(battery, ocv_vol);
pre_cap = ocv_cap;
battery->ocv_pre_dsoc = pre_soc;
battery->ocv_new_dsoc = ocv_soc;
if (abs(ocv_soc - pre_soc) >= battery->pdata->max_soc_offset) {
battery->ocv_pre_dsoc = pre_soc;
battery->ocv_new_dsoc = ocv_soc;
battery->is_max_soc_offset = true;
BAT_INFO("trigger max soc offset, dsoc: %d -> %d\n",
pre_soc, ocv_soc);
pre_soc = ocv_soc;
}
BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc);
} else if (battery->pwroff_min > 0) {
ocv_vol = rk817_bat_get_ocv_voltage(battery);
ocv_soc = rk817_bat_vol2soc(battery, ocv_vol);
ocv_cap = rk817_bat_vol2cap(battery, ocv_vol);
battery->force_pre_dsoc = pre_soc;
battery->force_new_dsoc = ocv_soc;
if (abs(ocv_soc - pre_soc) >= 80) {
battery->is_force_calib = true;
BAT_INFO("dsoc force calib: %d -> %d\n",
pre_soc, ocv_soc);
pre_soc = ocv_soc;
pre_cap = ocv_cap;
}
}
finish:
battery->dsoc = pre_soc;
battery->nac = pre_cap;
if (battery->nac < 0)
@@ -1653,10 +1883,10 @@ static void rk817_bat_init_fg(struct rk817_battery_device *battery)
rk817_bat_gg_con_init(battery);
rk817_bat_init_voltage_kb(battery);
rk817_bat_set_relax_sample(battery);
rk817_bat_ocv_thre(battery, 0xff);
rk817_bat_init_caltimer(battery);
rk817_bat_rsoc_init(battery);
rk817_bat_init_coulomb_cap(battery, battery->nac);
rk817_bat_init_ts_detect(battery);
DBG("rsoc%d, fcc = %d\n", battery->rsoc, battery->fcc);
rk817_bat_init_dsoc_algorithm(battery);
battery->qmax = rk817_bat_get_qmax(battery);
@@ -1674,7 +1904,119 @@ static void rk817_bat_init_fg(struct rk817_battery_device *battery)
DBG("probe init: battery->dsoc = %d, rsoc = %d, remain_cap = %d\n, bat_vol = %d\n, sys_vol = %d, qmax = %d\n",
battery->dsoc, battery->rsoc, battery->remain_cap,
battery->voltage_avg, battery->voltage_sys, battery->qmax);
DBG("OCV_THRE_VOL: 0x%x", rk817_bat_field_read(battery, OCV_THRE_VOL));
}
static u8 rk817_bat_decode_chrg_voltage(u32 chrg_voltage)
{
if (chrg_voltage == 0)
return 0xff;
if (chrg_voltage < 4150)
return CHRG_VOL_4100MV;
else if (chrg_voltage < 4200)
return CHRG_VOL_4100MV;
else if (chrg_voltage < 4250)
return CHRG_VOL_4200MV;
else if (chrg_voltage < 4300)
return CHRG_VOL_4250MV;
else if (chrg_voltage < 4350)
return CHRG_VOL_4300MV;
else if (chrg_voltage < 4400)
return CHRG_VOL_4350MV;
else if (chrg_voltage < 4450)
return CHRG_VOL_4400MV;
else
return CHRG_VOL_4450MV;
}
static u8 rk817_bat_decode_chrg_current(struct rk817_battery_device *battery,
u32 chrg_current)
{
int val;
if (chrg_current == 0)
return 0xff;
val = chrg_current * battery->pdata->sample_res / 10;
if (val < 1000)
return CHRG_CUR_500MA;
else if (val < 1500)
return CHRG_CUR_1000MA;
else if (val < 2000)
return CHRG_CUR_1500MA;
else if (val < 2500)
return CHRG_CUR_2000MA;
else if (val < 2750)
return CHRG_CUR_2500MA;
else if (val < 3000)
return CHRG_CUR_2750MA;
else if (val < 3500)
return CHRG_CUR_3000MA;
else
return CHRG_CUR_3500MA;
}
static int parse_temperature_chrg_table(struct rk817_battery_device *battery,
struct device_node *np)
{
int size, count;
int i, chrg_current, chrg_voltage;
const __be32 *list;
if (!of_find_property(np, "temperature_chrg_table", &size))
return 0;
list = of_get_property(np, "temperature_chrg_table", &size);
size /= sizeof(u32);
if (!size || (size % 3)) {
dev_err(battery->dev,
"invalid temperature_chrg_table: size=%d\n", size);
return -EINVAL;
}
count = size / 4;
battery->pdata->tc_count = count;
battery->pdata->tc_table = devm_kzalloc(battery->dev,
count * sizeof(*battery->pdata->tc_table),
GFP_KERNEL);
if (!battery->pdata->tc_table)
return -ENOMEM;
for (i = 0; i < count; i++) {
/* temperature */
battery->pdata->tc_table[i].temp_down = be32_to_cpu(*list++);
battery->pdata->tc_table[i].temp_up = be32_to_cpu(*list++);
chrg_current = be32_to_cpu(*list++);
chrg_voltage = be32_to_cpu(*list++);
/*
* because charge current lowest level is 500mA:
* higher than or equal 1000ma, select charge current;
* lower than 500ma, must select input current.
*/
if (chrg_current >= 500) {
battery->pdata->tc_table[i].chrg_current = chrg_current;
battery->pdata->tc_table[i].chrg_current_index = rk817_bat_decode_chrg_current(battery, chrg_current);
} else {
battery->pdata->tc_table[i].chrg_current = 0;
}
if (chrg_voltage >= 4100) {
battery->pdata->tc_table[i].chrg_voltage = chrg_voltage;
battery->pdata->tc_table[i].chrg_voltage_index = rk817_bat_decode_chrg_voltage(chrg_voltage);
} else {
battery->pdata->tc_table[i].chrg_voltage = 0;
}
DBG("temp%d: [%d, %d], chrg_current=%d, current_index: %d, chrg_voltage: %d, voltage_index: %d\n",
i, battery->pdata->tc_table[i].temp_down,
battery->pdata->tc_table[i].temp_up,
battery->pdata->tc_table[i].chrg_current,
battery->pdata->tc_table[i].chrg_current_index,
battery->pdata->tc_table[i].chrg_voltage,
battery->pdata->tc_table[i].chrg_voltage_index);
}
return 0;
}
static int rk817_bat_parse_dt(struct rk817_battery_device *battery)
@@ -1700,7 +2042,6 @@ static int rk817_bat_parse_dt(struct rk817_battery_device *battery)
pdata->sleep_filter_current = DEFAULT_SLP_FILTER_CUR;
pdata->bat_mode = MODE_BATTARY;
pdata->max_soc_offset = DEFAULT_MAX_SOC_OFFSET;
pdata->fake_full_soc = 100;
pdata->sample_res = DEFAULT_SAMPLE_RES;
pdata->charge_stay_awake = 0;
@@ -1746,11 +2087,6 @@ static int rk817_bat_parse_dt(struct rk817_battery_device *battery)
if (ret < 0)
dev_err(dev, "sample_res missing!\n");
ret = of_property_read_u32(np, "max_soc_offset",
&pdata->max_soc_offset);
if (ret < 0)
dev_err(dev, "max_soc_offset missing!\n");
ret = of_property_read_u32(np, "monitor_sec", &pdata->monitor_sec);
if (ret < 0)
dev_err(dev, "monitor_sec missing!\n");
@@ -1807,15 +2143,55 @@ static int rk817_bat_parse_dt(struct rk817_battery_device *battery)
ret = of_property_read_u32(np, "design_max_voltage",
&pdata->design_max_voltage);
if (ret < 0)
if (ret < 0) {
dev_err(dev, "battery design_max_voltage missing!\n");
pdata->design_max_voltage = pdata->ocv_table[pdata->ocv_size - 1];
}
ret = of_property_read_u32(np, "register_chg_psy",
&battery->is_register_chg_psy);
if (ret < 0 || !battery->is_register_chg_psy)
dev_err(dev, "not have to register chg psy!\n");
}
if (!of_find_property(np, "ntc_table", &length)) {
pdata->ntc_size = 0;
battery->temperature = VIRTUAL_TEMPERATURE;
} else {
/* get ntc degree base value */
ret = of_property_read_u32_index(np, "ntc_degree_from", 1,
&pdata->ntc_degree_from);
if (ret) {
dev_err(dev, "invalid ntc_degree_from\n");
return -EINVAL;
}
ret = of_property_read_u32_index(np, "ntc_degree_from", 0,
&out_value);
if (ret) {
dev_err(dev, "invalid ntc_degree_from\n");
return -EINVAL;
}
if (out_value)
pdata->ntc_degree_from = -pdata->ntc_degree_from;
pdata->ntc_size = length / sizeof(u32);
}
if (pdata->ntc_size) {
parse_temperature_chrg_table(battery, np);
size = sizeof(*pdata->ntc_table) * pdata->ntc_size;
pdata->ntc_table = devm_kzalloc(battery->dev, size, GFP_KERNEL);
if (!pdata->ntc_table)
return -ENOMEM;
ret = of_property_read_u32_array(np, "ntc_table",
pdata->ntc_table,
pdata->ntc_size);
if (ret < 0)
return ret;
}
DBG("the battery dts info dump:\n"
"bat_res:%d\n"
"res_sample:%d\n"
@@ -1825,7 +2201,6 @@ static int rk817_bat_parse_dt(struct rk817_battery_device *battery)
"sleep_exit_current:%d\n"
"sleep_filter_current:%d\n"
"monitor_sec:%d\n"
"max_soc_offset:%d\n"
"virtual_power:%d\n"
"pwroff_vol:%d\n",
pdata->bat_res,
@@ -1836,7 +2211,6 @@ static int rk817_bat_parse_dt(struct rk817_battery_device *battery)
pdata->sleep_exit_current,
pdata->sleep_filter_current,
pdata->monitor_sec,
pdata->max_soc_offset,
pdata->bat_mode,
pdata->pwroff_vol);
@@ -2276,6 +2650,20 @@ static void rk817_bat_smooth_algorithm(struct rk817_battery_device *battery)
delta_cap, battery->dsoc);
}
static void rk817_bat_init_capacity(struct rk817_battery_device *battery,
u32 cap)
{
int delta_cap;
delta_cap = cap - battery->remain_cap;
if (!delta_cap)
return;
battery->age_adjust_cap += delta_cap;
rk817_bat_init_coulomb_cap(battery, cap);
rk817_bat_smooth_algo_prepare(battery);
}
static void rk817_bat_finish_algorithm(struct rk817_battery_device *battery)
{
unsigned long finish_sec, soc_sec;
@@ -2321,6 +2709,54 @@ static void rk817_bat_finish_algorithm(struct rk817_battery_device *battery)
battery->dsoc = MAX_PERCENTAGE;
}
static void rk817_bat_update_age_fcc(struct rk817_battery_device *battery)
{
int fcc;
int remain_cap;
int age_keep_min;
fcc = battery->fcc * 1000;
remain_cap = fcc - battery->age_ocv_cap - battery->age_adjust_cap;
age_keep_min = base2min(battery->age_keep_sec);
DBG("%s: lock_fcc=%d, age_ocv_cap=%d, age_adjust_cap=%d, remain_cap=%d, age_allow_update=%d, age_keep_min=%d\n",
__func__, fcc, battery->age_ocv_cap, battery->age_adjust_cap, remain_cap,
battery->age_allow_update, age_keep_min);
if ((battery->chrg_status == CHARGE_FINISH) && (battery->age_allow_update) &&
(age_keep_min < battery->fcc * 60 / 2000)) {
battery->age_allow_update = false;
fcc = remain_cap * 100 * 1000 / DIV(100 * 1000 - battery->age_ocv_soc);
BAT_INFO("calc_cap=%d, age: soc=%d, cap=%d, level=%d, fcc:%d->%d?\n",
remain_cap, battery->age_ocv_soc,
battery->age_ocv_cap, battery->age_level, battery->fcc, fcc);
if ((fcc < EFFECTIVE_FULL_MAX_CAP(battery->pdata->design_capacity)) &&
(fcc > EFFECTIVE_FULL_MIN_CAP(battery->pdata->design_capacity))) {
BAT_INFO("fcc:%d->%d!\n", battery->fcc, fcc);
battery->fcc = fcc / 1000;
rk817_bat_init_capacity(battery, battery->fcc);
rk817_bat_save_fcc(battery, battery->fcc);
}
}
}
static void rk817_bat_wait_finish_sig(struct rk817_battery_device *battery)
{
int chrg_finish_vol = battery->pdata->design_max_voltage;
if (battery->chrg_status == CHARGE_FINISH)
return;
if ((battery->chrg_status == CHARGE_FINISH) &&
(battery->temperature >= VIRTUAL_TEMPERATURE) &&
(battery->voltage_avg > chrg_finish_vol - 150) && battery->age_allow_update) {
rk817_bat_update_age_fcc(battery);/* save new fcc*/
battery->age_allow_update = false;
}
}
static void rk817_bat_display_smooth(struct rk817_battery_device *battery)
{
if (battery->s2r && !battery->sleep_chrg_online) {
@@ -2412,6 +2848,8 @@ static void rk817_bat_print_time(struct rk817_battery_device *battery)
static void rk817_bat_output_info(struct rk817_battery_device *battery)
{
int index;
DBG("info start:\n");
DBG("info: voltage_k %d\n", battery->voltage_k);
DBG("info: voltage_b %d\n", battery->voltage_b);
@@ -2429,6 +2867,15 @@ static void rk817_bat_output_info(struct rk817_battery_device *battery)
battery->voltage_avg, battery->expected_voltage, battery->current_avg,
battery->sm_linek, battery->remain_cap, battery->sm_remain_cap);
rk817_bat_print_time(battery);
if (battery->pdata->ntc_size) {
index = battery->charge_index;
DBG("Temperature: %d charger current: %dmA, index: %d, charger voltage: %dmV, index: %d\n",
battery->temperature,
battery->pdata->tc_table[index].chrg_current,
battery->pdata->tc_table[index].chrg_current_index,
battery->pdata->tc_table[index].chrg_voltage,
battery->pdata->tc_table[index].chrg_voltage_index);
}
DBG("info END.\n");
}
@@ -2440,11 +2887,14 @@ static void rk817_battery_work(struct work_struct *work)
bat_delay_work.work);
rk817_bat_update_fg_info(battery);
rk817_bat_wait_finish_sig(battery);
rk817_bat_lowpwr_check(battery);
rk817_bat_display_smooth(battery);
rk817_bat_update_fcc(battery);
rk817_bat_power_supply_changed(battery);
rk817_bat_save_data(battery);
rk817_bat_stay_awake(battery);
rk817_bat_update_temperature(battery);
rk817_bat_output_info(battery);
if (rk817_bat_field_read(battery, CUR_CALIB_UPD)) {
@@ -2712,7 +3162,7 @@ static int rk817_bat_rtc_sleep_sec(struct rk817_battery_device *battery)
static void rk817_bat_relife_age_flag(struct rk817_battery_device *battery)
{
u8 ocv_soc, ocv_cap, soc_level;
int age_level, ocv_soc, ocv_cap;
if (battery->voltage_relax <= 0)
return;
@@ -2736,38 +3186,24 @@ static void rk817_bat_relife_age_flag(struct rk817_battery_device *battery)
else
battery->age_level = 80;
/*soc_level = rk818_bat_get_age_level(battery);*/
soc_level = 0;
if (soc_level > battery->age_level) {
age_level = rk817_bat_get_age_level(battery);
if (age_level > battery->age_level) {
battery->age_allow_update = false;
age_level -= 5;
if (age_level <= 80)
age_level = 80;
rk817_bat_save_age_level(battery, age_level);
} else {
battery->age_allow_update = true;
battery->age_keep_sec = get_boot_sec();
}
BAT_INFO("resume: age_vol:%d, age_ocv_cap:%d, age_ocv_soc:%d\n"
"soc_level:%d, age_allow_update:%d\n"
"age_level:%d\n",
BAT_INFO("resume: age_vol:%d, age_ocv_cap:%d, age_ocv_soc:%d, age_allow_update:%d, age_level:%d\n",
battery->age_voltage, battery->age_ocv_cap,
ocv_soc, soc_level,
battery->age_allow_update, battery->age_level);
ocv_soc, battery->age_allow_update, battery->age_level);
}
}
static void rk817_bat_init_capacity(struct rk817_battery_device *battery,
u32 cap)
{
int delta_cap;
delta_cap = cap - battery->remain_cap;
if (!delta_cap)
return;
battery->age_adjust_cap += delta_cap;
rk817_bat_init_coulomb_cap(battery, cap);
rk817_bat_smooth_algo_prepare(battery);
}
static void rk817_bat_relax_vol_calib(struct rk817_battery_device *battery)
{
int soc, cap, vol;

View File

@@ -273,6 +273,10 @@ static const struct of_device_id rockchip_npu_of_match[] = {
.compatible = "rockchip,rk3576",
.data = (void *)&rk3576_npu_opp_data,
},
{
.compatible = "rockchip,rk3576s",
.data = (void *)&rk3576_npu_opp_data,
},
{
.compatible = "rockchip,rk3588",
.data = (void *)&rk3588_npu_opp_data,