diff --git a/arch/arm/configs/rv1126b-evb.config b/arch/arm/configs/rv1126b-evb.config index add7b901ba15..8b0149902338 100644 --- a/arch/arm/configs/rv1126b-evb.config +++ b/arch/arm/configs/rv1126b-evb.config @@ -47,6 +47,7 @@ CONFIG_VIDEOBUF2_DMA_SG=y CONFIG_VIDEO_GC2053=m CONFIG_VIDEO_GC8613=m CONFIG_VIDEO_IMX415=m +CONFIG_VIDEO_IMX586=m CONFIG_VIDEO_OS04A10=m CONFIG_VIDEO_PS5458=m # CONFIG_VIDEO_RK_IRCUT is not set diff --git a/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/arch/arm64/boot/dts/rockchip/rk3528.dtsi index b0fe21c73358..aec7a55ce276 100644 --- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi @@ -621,9 +621,8 @@ <0x0 0xfe000000 0x0 0x400000>, <0x0 0xfc000000 0x0 0x100000>; reg-names = "pcie-apb", "pcie-dbi", "config"; - resets = <&cru SRST_RESETN_PCIE_POWER_UP>, <&cru SRST_PRESETN_PCIE>, - <&cru SRST_PRESETN_CRU_PCIE>; - reset-names = "pcie", "periph", "preset_cru"; + resets = <&cru SRST_RESETN_PCIE_POWER_UP>, <&cru SRST_PRESETN_PCIE>; + reset-names = "pcie", "periph"; status = "disabled"; pcie2x1_intc: legacy-interrupt-controller { diff --git a/arch/arm64/boot/dts/rockchip/rk3562.dtsi b/arch/arm64/boot/dts/rockchip/rk3562.dtsi index ebd92a542460..c057ce7362ca 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562.dtsi @@ -709,7 +709,6 @@ rkcif_mipi_lvds: rkcif-mipi-lvds { compatible = "rockchip,rkcif-mipi-lvds"; rockchip,hw = <&rkcif>; - iommus = <&rkcif_mmu>; status = "disabled"; }; @@ -740,7 +739,6 @@ rkcif_mipi_lvds1: rkcif-mipi-lvds1 { compatible = "rockchip,rkcif-mipi-lvds"; rockchip,hw = <&rkcif>; - iommus = <&rkcif_mmu>; status = "disabled"; }; @@ -771,7 +769,6 @@ rkcif_mipi_lvds2: rkcif-mipi-lvds2 { compatible = "rockchip,rkcif-mipi-lvds"; rockchip,hw = <&rkcif>; - iommus = <&rkcif_mmu>; status = "disabled"; }; @@ -802,7 +799,6 @@ rkcif_mipi_lvds3: rkcif-mipi-lvds3 { compatible = "rockchip,rkcif-mipi-lvds"; rockchip,hw = <&rkcif>; - iommus = <&rkcif_mmu>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi index 98f38c8a7d08..fac0f509bfdd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb7-v11.dtsi @@ -937,11 +937,11 @@ }; &usbhost3_0 { - status = "disabled"; + status = "okay"; }; &usbhost_dwc3_0 { - status = "disabled"; + status = "okay"; }; &work_led { diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi index e4a47be9e283..db5eb453ce6d 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb-cam-csi0.dtsi @@ -56,6 +56,12 @@ remote-endpoint = <&sc635hai_out>; data-lanes = <1 2 3 4>; }; + + csi_dphy_input7: endpoint@8 { + reg = <8>; + remote-endpoint = <&imx586_out>; + data-lanes = <1 2 3 4>; + }; }; port@1 { reg = <1>; @@ -115,6 +121,26 @@ }; }; + imx586: imx586@1a { + compatible = "sony,imx586"; + reg = <0x1a>; + clocks = <&cru CLK_MIPI0_OUT2IO>; + clock-names = "xvclk"; + reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_clk0_pins>; + rockchip,camera-module-index = <0>; + rockchip,camera-module-facing = "back"; + rockchip,camera-module-name = "default"; + rockchip,camera-module-lens-name = "default"; + port { + imx586_out: endpoint { + remote-endpoint = <&csi_dphy_input7>; + data-lanes = <1 2 3 4>; + }; + }; + }; + sc450ai: sc450ai@30 { compatible = "smartsens,sc450ai"; status = "okay"; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts index 9b6b34255f0c..9ab0043261cb 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts @@ -28,9 +28,130 @@ rockchip,sleep-pin-config = < (0 + | RKPM_SLEEP_PIN0_EN | RKPM_SLEEP_PIN2_EN ) (0 + | RKPM_SLEEP_PIN0_ACT_LOW + ) + >; + + rockchip,sleep-io-config = < + /* pmic_sleep */ + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(0) + ) + /* reset */ + #if 0 + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_NONE + | RKPM_IO_CFG_ID(1) + ) + #endif + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(2) + ) + (0 + | RKPM_IO_CFG_PULL_NONE + | RKPM_IO_CFG_ID(3) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(4) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_UP + | RKPM_IO_CFG_ID(5) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(6) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_UP + | RKPM_IO_CFG_ID(7) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(8) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(9) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(10) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(11) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(12) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(20) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(21) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(22) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(23) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(24) + ) + (0 + | RKPM_IO_CFG_IOMUX_GPIO + | RKPM_IO_CFG_GPIO_DIR_INPUT + | RKPM_IO_CFG_PULL_DOWN + | RKPM_IO_CFG_ID(25) ) >; }; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi index 262b8c2674a2..ee65864a5060 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dtsi @@ -274,7 +274,7 @@ regulator-boot-on; regulator-always-on; regulator-state-mem { - regulator-on-in-suspend; + regulator-off-in-suspend; regulator-suspend-microvolt = <900000>; }; }; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts index 24d56147893f..77b9f3cd1b9d 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts @@ -441,6 +441,10 @@ | RKPM_IO_CFG_ID(2) ) (0 + | RKPM_IO_CFG_PULL_NONE + | RKPM_IO_CFG_ID(3) + ) + (0 | RKPM_IO_CFG_IOMUX_GPIO | RKPM_IO_CFG_GPIO_DIR_INPUT | RKPM_IO_CFG_PULL_UP @@ -479,22 +483,20 @@ (0 | RKPM_IO_CFG_IOMUX_GPIO | RKPM_IO_CFG_GPIO_DIR_INPUT - | RKPM_IO_CFG_PULL_UP + | RKPM_IO_CFG_PULL_DOWN | RKPM_IO_CFG_ID(10) ) /* uart0 tx */ - #if 0 (0 | RKPM_IO_CFG_IOMUX_GPIO | RKPM_IO_CFG_GPIO_DIR_INPUT - | RKPM_IO_CFG_PULL_UP + | RKPM_IO_CFG_PULL_DOWN | RKPM_IO_CFG_ID(11) ) - #endif (0 | RKPM_IO_CFG_IOMUX_GPIO | RKPM_IO_CFG_GPIO_DIR_INPUT - | RKPM_IO_CFG_PULL_UP + | RKPM_IO_CFG_PULL_DOWN | RKPM_IO_CFG_ID(12) ) (0 diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts index d7c69c18fb26..4e0d11055849 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb3-v10.dts @@ -448,6 +448,28 @@ status = "okay"; }; +&rockchip_suspend { + status = "okay"; + + rockchip,sleep-pin-config = < + (0 + ) + >; + rockchip,sleep-mode-config = < + (0 + | RKPM_SLP_ARMOFF_LOGOFF + | RKPM_SLP_PMU_PMUALIVE_32K + | RKPM_SLP_PMU_DIS_OSC + | RKPM_SLP_LP_PR + ) + >; +}; + +&rtc { + rockchip,rtc-suspend-bypass; + status = "okay"; +}; + &pinctrl { sdio-pwrseq { wifi_enable_h: wifi-enable-h { diff --git a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi index d07837421cda..d3c0d1dfb338 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi @@ -580,7 +580,7 @@ method = "smc"; }; - reserved-memory { + reserved_memory: reserved-memory { #address-cells = <1>; #size-cells = <1>; ranges; @@ -915,20 +915,6 @@ }; }; }; - npu_thermal: npu-thermal { - polling-delay-passive = <20>; /* milliseconds */ - polling-delay = <1000>; /* milliseconds */ - thermal-sensors = <&tsadc 1>; - trips { - bigcore_crit: bigcore-crit { - /* millicelsius */ - temperature = <115000>; - /* millicelsius */ - hysteresis = <2000>; - type = "critical"; - }; - }; - }; }; timer { @@ -3331,6 +3317,18 @@ opp-microvolt-L0 = <900000 900000 1050000>; opp-microvolt-L1 = <875000 875000 1050000>; }; + opp-510000000 { + opp-hz = /bits/ 64 <510000000>; + opp-microvolt = <850000 850000 1050000>; + opp-microvolt-L0 = <900000 900000 1050000>; + opp-microvolt-L1 = <875000 875000 1050000>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <850000 850000 1050000>; + opp-microvolt-L0 = <900000 900000 1050000>; + opp-microvolt-L1 = <875000 875000 1050000>; + }; opp-700000000 { opp-hz = /bits/ 64 <700000000>; opp-microvolt = <850000 850000 1050000>; diff --git a/drivers/clk/rockchip/clk-pvtpll.c b/drivers/clk/rockchip/clk-pvtpll.c index 380bdc02481b..b618759b341b 100644 --- a/drivers/clk/rockchip/clk-pvtpll.c +++ b/drivers/clk/rockchip/clk-pvtpll.c @@ -193,6 +193,8 @@ static struct pvtpll_table rv1126b_npu_pvtpll_table[] = { ROCKCHIP_PVTPLL_VOLT_SEL(900000000, 0, 14, 1), ROCKCHIP_PVTPLL_VOLT_SEL(800000000, 0, 18, 1), ROCKCHIP_PVTPLL_VOLT_SEL(700000000, 0, 36, 3), + ROCKCHIP_PVTPLL_VOLT_SEL(600000000, 0, 60, 3), + ROCKCHIP_PVTPLL_VOLT_SEL(510000000, 0, 108, 3), }; static struct pvtpll_table rk3506_core_pvtpll_table[] = { diff --git a/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c b/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c index d181f328046c..bc51185f8556 100644 --- a/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c +++ b/drivers/iio/imu/inv_icm42670/inv_icm42670_core.c @@ -1342,17 +1342,8 @@ static int __maybe_unused sleep_icm42670_resume(struct device *dev) struct icm42670_data *st = iio_priv(dev_get_drvdata(dev)); struct iio_dev *indio_dev = dev_get_drvdata(dev); - mutex_lock(&st->lock); - - if (!pm_runtime_suspended(dev)) - goto out_unlock; - usleep_range(3000, 4000); - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - icm42670_set_odr(st, ICM42670_GYRO, st->gyro_frequency_buff); icm42670_set_odr(st, ICM42670_ACCEL, st->accel_frequency_buff); icm42670_set_lpf_bw(st, ICM42670_ACCEL, st->accel_lpf_bw_buff); @@ -1360,8 +1351,6 @@ static int __maybe_unused sleep_icm42670_resume(struct device *dev) ret = icm42670_set_enable(indio_dev, 1); -out_unlock: - mutex_unlock(&st->lock); return ret; } @@ -1375,11 +1364,6 @@ static int __maybe_unused sleep_icm42670_suspend(struct device *dev) struct iio_dev *indio_dev = dev_get_drvdata(dev); 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; @@ -1387,8 +1371,6 @@ static int __maybe_unused sleep_icm42670_suspend(struct device *dev) ret = icm42670_set_enable(indio_dev, 0); -out_unlock: - mutex_unlock(&st->lock); return ret; } diff --git a/drivers/media/i2c/sc850sl.c b/drivers/media/i2c/sc850sl.c index 51cae601bff2..4404866b6c91 100644 --- a/drivers/media/i2c/sc850sl.c +++ b/drivers/media/i2c/sc850sl.c @@ -8,6 +8,7 @@ * V0.0X01.0X02 change power_gpio to pwdn_gpio * V0.0X01.0X03 support thunder boot * V0.0X01.0X04 support sleep/wake up + * V0.0X01.0X05 unified standby hw mode * */ @@ -33,7 +34,7 @@ #include "../platform/rockchip/isp/rkisp_tb_helper.h" #include "cam-sleep-wakeup.h" -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x04) +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x05) #ifndef V4L2_CID_DIGITAL_GAIN #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN @@ -121,7 +122,7 @@ #define SC850SL_LGAIN 0 #define SC850SL_SGAIN 1 -static const char * const sc850sl_supply_names[] = { +static const char *const sc850sl_supply_names[] = { "dvdd", // Digital core power "dovdd", // Digital I/O power "avdd", // Analog power @@ -181,10 +182,12 @@ struct sc850sl { const char *module_facing; const char *module_name; const char *len_name; + u32 standby_hw; u32 cur_vts; bool has_init_exp; bool is_thunderboot; bool is_first_streamoff; + bool is_standby; struct preisp_hdrae_exp_s init_hdrae_exp; struct cam_sw_info *cam_sw_info; }; @@ -413,7 +416,7 @@ static const struct sc850sl_mode supported_modes[] = { .denominator = 300000, }, .exp_def = 0x08c0, - .hts_def = 0x0226*5-0x180, + .hts_def = 0x0226 * 5 - 0x180, .vts_def = 0x08ca, .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, .reg_list = sc850sl_linear10bit_3840x2160_regs, @@ -428,7 +431,7 @@ static const u32 bus_code[] = { MEDIA_BUS_FMT_SBGGR10_1X10, }; -static const char * const sc850sl_test_pattern_menu[] = { +static const char *const sc850sl_test_pattern_menu[] = { "Disabled", "Vertical Color Bar Type 1", "Vertical Color Bar Type 2", @@ -442,7 +445,7 @@ static const s64 link_freq_items[] = { /* Write registers up to 4 at a time */ static int sc850sl_write_reg(struct i2c_client *client, u16 reg, - u32 len, u32 val) + u32 len, u32 val) { u32 buf_i, val_i; u8 buf[6]; @@ -470,21 +473,21 @@ static int sc850sl_write_reg(struct i2c_client *client, u16 reg, } static int sc850sl_write_array(struct i2c_client *client, - const struct regval *regs) + const struct regval *regs) { u32 i; int ret = 0; for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) { ret = sc850sl_write_reg(client, regs[i].addr, - SC850SL_REG_VALUE_08BIT, regs[i].val); + SC850SL_REG_VALUE_08BIT, regs[i].val); } return ret; } /* Read registers up to 4 at a time */ static int sc850sl_read_reg(struct i2c_client *client, u16 reg, unsigned int len, - u32 *val) + u32 *val) { struct i2c_msg msgs[2]; u8 *data_be_p; @@ -518,7 +521,7 @@ static int sc850sl_read_reg(struct i2c_client *client, u16 reg, unsigned int len } static int sc850sl_get_reso_dist(const struct sc850sl_mode *mode, - struct v4l2_mbus_framefmt *framefmt) + struct v4l2_mbus_framefmt *framefmt) { return abs(mode->width - framefmt->width) + abs(mode->height - framefmt->height); @@ -555,12 +558,12 @@ static void sc850sl_change_mode(struct sc850sl *sc850sl, const struct sc850sl_mo sc850sl->cur_mode = mode; sc850sl->cur_vts = sc850sl->cur_mode->vts_def; dev_info(&sc850sl->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n", - mode->width, mode->height, mode->hdr_mode); + mode->width, mode->height, mode->hdr_mode); } static int sc850sl_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct sc850sl *sc850sl = to_sc850sl(sd); const struct sc850sl_mode *mode; @@ -592,7 +595,7 @@ static int sc850sl_set_fmt(struct v4l2_subdev *sd, 1, vblank_def); __v4l2_ctrl_s_ctrl(sc850sl->link_freq, mode->mipi_freq_idx); pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / - mode->bpp * 2 * SC850SL_4LANES; + mode->bpp * 2 * SC850SL_4LANES; __v4l2_ctrl_s_ctrl_int64(sc850sl->pixel_rate, pixel_rate); sc850sl->cur_fps = mode->max_fps; sc850sl->cur_vts = mode->vts_def; @@ -604,8 +607,8 @@ static int sc850sl_set_fmt(struct v4l2_subdev *sd, } static int sc850sl_get_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_format *fmt) { struct sc850sl *sc850sl = to_sc850sl(sd); const struct sc850sl_mode *mode = sc850sl->cur_mode; @@ -634,8 +637,8 @@ static int sc850sl_get_fmt(struct v4l2_subdev *sd, } static int sc850sl_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_mbus_code_enum *code) { if (code->index >= ARRAY_SIZE(bus_code)) return -EINVAL; @@ -645,8 +648,8 @@ static int sc850sl_enum_mbus_code(struct v4l2_subdev *sd, } static int sc850sl_enum_frame_sizes(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_size_enum *fse) { struct sc850sl *sc850sl = to_sc850sl(sd); @@ -670,18 +673,18 @@ static int sc850sl_enable_test_pattern(struct sc850sl *sc850sl, u32 pattern) int ret = 0; ret = sc850sl_read_reg(sc850sl->client, SC850SL_REG_TEST_PATTERN, - SC850SL_REG_VALUE_08BIT, &val); + SC850SL_REG_VALUE_08BIT, &val); if (pattern) val |= SC850SL_TEST_PATTERN_ENABLE; else val &= ~SC850SL_TEST_PATTERN_ENABLE; ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_TEST_PATTERN, - SC850SL_REG_VALUE_08BIT, val); + SC850SL_REG_VALUE_08BIT, val); return ret; } static int sc850sl_g_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *fi) + struct v4l2_subdev_frame_interval *fi) { struct sc850sl *sc850sl = to_sc850sl(sd); const struct sc850sl_mode *mode = sc850sl->cur_mode; @@ -718,7 +721,7 @@ static const struct sc850sl_mode *sc850sl_find_mode(struct sc850sl *sc850sl, int } static int sc850sl_s_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_frame_interval *fi) + struct v4l2_subdev_frame_interval *fi) { struct sc850sl *sc850sl = to_sc850sl(sd); const struct sc850sl_mode *mode = NULL; @@ -764,7 +767,7 @@ static int sc850sl_s_frame_interval(struct v4l2_subdev *sd, } static int sc850sl_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, - struct v4l2_mbus_config *config) + struct v4l2_mbus_config *config) { config->type = V4L2_MBUS_CSI2_DPHY; config->bus.mipi_csi2.num_data_lanes = SC850SL_4LANES; @@ -773,7 +776,7 @@ static int sc850sl_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, } static void sc850sl_get_module_inf(struct sc850sl *sc850sl, - struct rkmodule_inf *inf) + struct rkmodule_inf *inf) { memset(inf, 0, sizeof(*inf)); strscpy(inf->base.sensor, SC850SL_NAME, sizeof(inf->base.sensor)); @@ -785,11 +788,11 @@ static void sc850sl_get_module_inf(struct sc850sl *sc850sl, /* mode: 0 = lgain 1 = sgain */ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) { - u32 ANA_Fine_gainx64 = 1, DIG_Fine_gainx1000 = 1; + u32 ANA_Fine_gainx64 = 1; u32 Dcg_gainx1000; u8 Coarse_gain = 1, DIG_gain = 1; u8 ANA_Fine_gain_reg = 0x40, DIG_Fine_gain_reg = 0; - u8 Dcg_gain_reg, Coarse_gain_reg, DIG_gain_reg; + u8 Coarse_gain_reg, DIG_gain_reg; int ret = 0; u64 val = 0; @@ -803,8 +806,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Dcg_gainx1000 = 1000; Coarse_gain = 1; DIG_gain = 1; - DIG_Fine_gainx1000 = 1000; - Dcg_gain_reg = 0; Coarse_gain_reg = 0x03; DIG_gain_reg = 0x0; DIG_Fine_gain_reg = 0x80; @@ -812,8 +813,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Dcg_gainx1000 = 1000; Coarse_gain = 2; DIG_gain = 1; - DIG_Fine_gainx1000 = 1000; - Dcg_gain_reg = 0; Coarse_gain_reg = 0x07; DIG_gain_reg = 0x0; DIG_Fine_gain_reg = 0x80; @@ -821,8 +820,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Dcg_gainx1000 = 3125; Coarse_gain = 1; DIG_gain = 1; - DIG_Fine_gainx1000 = 1000; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x23; DIG_gain_reg = 0x0; DIG_Fine_gain_reg = 0x80; @@ -830,8 +827,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Dcg_gainx1000 = 3125; Coarse_gain = 2; DIG_gain = 1; - DIG_Fine_gainx1000 = 1000; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x27; DIG_gain_reg = 0x0; DIG_Fine_gain_reg = 0x80; @@ -839,8 +834,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Dcg_gainx1000 = 3125; Coarse_gain = 4; DIG_gain = 1; - DIG_Fine_gainx1000 = 1000; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x2f; DIG_gain_reg = 0x0; DIG_Fine_gain_reg = 0x80; @@ -848,8 +841,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Dcg_gainx1000 = 3125; Coarse_gain = 8; DIG_gain = 1; - DIG_Fine_gainx1000 = 1000; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x3f; DIG_gain_reg = 0x0; DIG_Fine_gain_reg = 0x80; @@ -858,7 +849,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Coarse_gain = 8; DIG_gain = 1; ANA_Fine_gainx64 = 127; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x3f; DIG_gain_reg = 0x0; ANA_Fine_gain_reg = 0x7f; @@ -867,7 +857,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Coarse_gain = 8; DIG_gain = 2; ANA_Fine_gainx64 = 127; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x3f; DIG_gain_reg = 0x1; ANA_Fine_gain_reg = 0x7f; @@ -876,7 +865,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Coarse_gain = 8; DIG_gain = 4; ANA_Fine_gainx64 = 127; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x3f; DIG_gain_reg = 0x3; ANA_Fine_gain_reg = 0x7f; @@ -885,7 +873,6 @@ static int sc850sl_set_gain_reg(struct sc850sl *sc850sl, u32 gain, int mode) Coarse_gain = 8; DIG_gain = 8; ANA_Fine_gainx64 = 127; - Dcg_gain_reg = 1; Coarse_gain_reg = 0x3f; DIG_gain_reg = 0x7; ANA_Fine_gain_reg = 0x7f; @@ -973,7 +960,7 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) */ if (sc850sl->cam_sw_info) memcpy(&sc850sl->cam_sw_info->hdr_ae, (struct preisp_hdrae_exp_s *)(arg), - sizeof(struct preisp_hdrae_exp_s)); + sizeof(struct preisp_hdrae_exp_s)); break; case RKMODULE_SET_HDR_CFG: @@ -983,14 +970,14 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) w = sc850sl->cur_mode->width; h = sc850sl->cur_mode->height; dst_fps = DIV_ROUND_CLOSEST(sc850sl->cur_mode->max_fps.denominator, - sc850sl->cur_mode->max_fps.numerator); + sc850sl->cur_mode->max_fps.numerator); for (i = 0; i < sc850sl->cfg_num; i++) { if (w == supported_modes[i].width && h == supported_modes[i].height && supported_modes[i].hdr_mode == hdr_cfg->hdr_mode && supported_modes[i].bus_fmt == sc850sl->cur_mode->bus_fmt) { cur_fps = DIV_ROUND_CLOSEST(supported_modes[i].max_fps.denominator, - supported_modes[i].max_fps.numerator); + supported_modes[i].max_fps.numerator); cur_dist = abs(cur_fps - dst_fps); if (cur_best_fit_dist == -1 || cur_dist < cur_best_fit_dist) { cur_best_fit_dist = cur_dist; @@ -1013,17 +1000,17 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) h = mode->vts_def - mode->height; __v4l2_ctrl_modify_range(sc850sl->hblank, w, w, 1, w); __v4l2_ctrl_modify_range(sc850sl->vblank, h, - SC850SL_VTS_MAX - mode->height, - 1, h); + SC850SL_VTS_MAX - mode->height, + 1, h); __v4l2_ctrl_s_ctrl(sc850sl->link_freq, mode->mipi_freq_idx); pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / - mode->bpp * 2 * SC850SL_4LANES; + mode->bpp * 2 * SC850SL_4LANES; __v4l2_ctrl_s_ctrl_int64(sc850sl->pixel_rate, pixel_rate); sc850sl->cur_fps = mode->max_fps; sc850sl->cur_vts = mode->vts_def; dev_info(&sc850sl->client->dev, - "sensor mode: %d\n", mode->hdr_mode); + "sensor mode: %d\n", mode->hdr_mode); } break; case RKMODULE_GET_MODULE_INFO: @@ -1040,25 +1027,31 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) stream = *((u32 *)arg); if (stream) { - ret = sc850sl_write_reg(sc850sl->client, 0x3019, - SC850SL_REG_VALUE_08BIT, - 0xf0); - ret = sc850sl_write_reg(sc850sl->client, 0x3018, - SC850SL_REG_VALUE_08BIT, - 0x7a); - ret = sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE, - SC850SL_REG_VALUE_08BIT, - SC850SL_MODE_STREAMING); + ret |= sc850sl_write_reg(sc850sl->client, 0x3019, + SC850SL_REG_VALUE_08BIT, + 0xf0); + ret |= sc850sl_write_reg(sc850sl->client, 0x3018, + SC850SL_REG_VALUE_08BIT, + 0x7a); + ret |= sc850sl_write_reg(sc850sl->client, 0x302c, + SC850SL_REG_VALUE_08BIT, + 0x00); + ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE, + SC850SL_REG_VALUE_08BIT, + SC850SL_MODE_STREAMING); } else { - ret = sc850sl_write_reg(sc850sl->client, 0x3018, - SC850SL_REG_VALUE_08BIT, - 0x7f); - ret = sc850sl_write_reg(sc850sl->client, 0x3019, - SC850SL_REG_VALUE_08BIT, - 0xff); - ret = sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE, - SC850SL_REG_VALUE_08BIT, - SC850SL_MODE_SW_STANDBY); + ret |= sc850sl_write_reg(sc850sl->client, 0x3018, + SC850SL_REG_VALUE_08BIT, + 0x7f); + ret |= sc850sl_write_reg(sc850sl->client, 0x3019, + SC850SL_REG_VALUE_08BIT, + 0xff); + ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE, + SC850SL_REG_VALUE_08BIT, + SC850SL_MODE_SW_STANDBY); + ret |= sc850sl_write_reg(sc850sl->client, 0x302c, + SC850SL_REG_VALUE_08BIT, + 0x0f); } break; @@ -1077,7 +1070,7 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) #ifdef CONFIG_COMPAT static long sc850sl_compat_ioctl32(struct v4l2_subdev *sd, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { void __user *up = compat_ptr(arg); struct rkmodule_inf *inf; @@ -1241,7 +1234,7 @@ static int __sc850sl_start_stream(struct sc850sl *sc850sl) /* In case these controls are set before streaming */ if (sc850sl->has_init_exp && sc850sl->cur_mode->hdr_mode != NO_HDR) { ret = sc850sl_ioctl(&sc850sl->subdev, PREISP_CMD_SET_HDRAE_EXP, - &sc850sl->init_hdrae_exp); + &sc850sl->init_hdrae_exp); if (ret) { dev_err(&sc850sl->client->dev, "init exp fail in hdr mode\n"); @@ -1250,7 +1243,7 @@ static int __sc850sl_start_stream(struct sc850sl *sc850sl) } } return sc850sl_write_reg(sc850sl->client, SC850SL_REG_CTRL_MODE, - SC850SL_REG_VALUE_08BIT, SC850SL_MODE_STREAMING); + SC850SL_REG_VALUE_08BIT, SC850SL_MODE_STREAMING); } static int __sc850sl_stop_stream(struct sc850sl *sc850sl) @@ -1272,8 +1265,8 @@ static int sc850sl_s_stream(struct v4l2_subdev *sd, int on) int ret = 0; dev_info(&sc850sl->client->dev, "s_stream: %d. %dx%d, hdr: %d, bpp: %d\n", - on, sc850sl->cur_mode->width, sc850sl->cur_mode->height, - sc850sl->cur_mode->hdr_mode, sc850sl->cur_mode->bpp); + on, sc850sl->cur_mode->width, sc850sl->cur_mode->height, + sc850sl->cur_mode->hdr_mode, sc850sl->cur_mode->bpp); mutex_lock(&sc850sl->mutex); on = !!on; @@ -1328,9 +1321,9 @@ static int sc850sl_s_power(struct v4l2_subdev *sd, int on) } if (!sc850sl->is_thunderboot) { ret |= sc850sl_write_reg(sc850sl->client, - SC850SL_SOFTWARE_RESET_REG, - SC850SL_REG_VALUE_08BIT, - 0x01); + SC850SL_SOFTWARE_RESET_REG, + SC850SL_REG_VALUE_08BIT, + 0x01); if (ret) { v4l2_err(sd, "could not set init registers\n"); pm_runtime_put_noidle(&client->dev); @@ -1446,6 +1439,11 @@ static int sc850sl_resume(struct device *dev) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct sc850sl *sc850sl = to_sc850sl(sd); + if (sc850sl->standby_hw) { + dev_info(dev, "resume standby!"); + return 0; + } + cam_sw_prepare_wakeup(sc850sl->cam_sw_info, dev); usleep_range(4000, 5000); @@ -1456,7 +1454,7 @@ static int sc850sl_resume(struct device *dev) if (sc850sl->has_init_exp && sc850sl->cur_mode != NO_HDR) { // hdr mode ret = sc850sl_ioctl(&sc850sl->subdev, PREISP_CMD_SET_HDRAE_EXP, - &sc850sl->cam_sw_info->hdr_ae); + &sc850sl->cam_sw_info->hdr_ae); if (ret) { dev_err(&sc850sl->client->dev, "set exp fail in hdr mode\n"); return ret; @@ -1471,6 +1469,11 @@ static int sc850sl_suspend(struct device *dev) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct sc850sl *sc850sl = to_sc850sl(sd); + if (sc850sl->standby_hw) { + dev_info(dev, "suspend standby!"); + return 0; + } + cam_sw_write_array_cb_init(sc850sl->cam_sw_info, client, (void *)sc850sl->cur_mode->reg_list, (sensor_write_array)sc850sl_write_array); @@ -1508,7 +1511,7 @@ static int sc850sl_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct sc850sl *sc850sl = to_sc850sl(sd); struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->state, 0); + v4l2_subdev_get_try_format(sd, fh->state, 0); const struct sc850sl_mode *def_mode = &supported_modes[0]; mutex_lock(&sc850sl->mutex); @@ -1526,8 +1529,8 @@ static int sc850sl_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) #endif static int sc850sl_enum_frame_interval(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_interval_enum *fie) + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_frame_interval_enum *fie) { struct sc850sl *sc850sl = to_sc850sl(sd); @@ -1580,7 +1583,7 @@ static int sc850sl_get_selection(struct v4l2_subdev *sd, static const struct dev_pm_ops sc850sl_pm_ops = { SET_RUNTIME_PM_OPS(sc850sl_runtime_suspend, - sc850sl_runtime_resume, NULL) + sc850sl_runtime_resume, NULL) SET_LATE_SYSTEM_SLEEP_PM_OPS(sc850sl_suspend, sc850sl_resume) }; @@ -1631,7 +1634,7 @@ static void sc850sl_modify_fps_info(struct sc850sl *sc850sl) static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) { struct sc850sl *sc850sl = container_of(ctrl->handler, - struct sc850sl, ctrl_handler); + struct sc850sl, ctrl_handler); struct i2c_client *client = sc850sl->client; s64 max; int ret = 0; @@ -1649,6 +1652,11 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) break; } + if (sc850sl->standby_hw && sc850sl->is_standby) { + dev_dbg(&client->dev, "%s: is_standby=true, will return\n", __func__); + return 0; + } + if (!pm_runtime_get_if_in_use(&client->dev)) return 0; @@ -1661,9 +1669,9 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) SC850SL_REG_VALUE_08BIT, SC850SL_FETCH_EXP_H(ctrl->val)); ret |= sc850sl_write_reg(sc850sl->client, - SC850SL_REG_EXP_LONG_M, - SC850SL_REG_VALUE_08BIT, - SC850SL_FETCH_EXP_M(ctrl->val)); + SC850SL_REG_EXP_LONG_M, + SC850SL_REG_VALUE_08BIT, + SC850SL_FETCH_EXP_M(ctrl->val)); ret |= sc850sl_write_reg(sc850sl->client, SC850SL_REG_EXP_LONG_L, SC850SL_REG_VALUE_08BIT, @@ -1693,7 +1701,7 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_HFLIP: ret = sc850sl_read_reg(sc850sl->client, SC850SL_FLIP_REG, - SC850SL_REG_VALUE_08BIT, &val); + SC850SL_REG_VALUE_08BIT, &val); if (ret) break; if (ctrl->val) @@ -1701,11 +1709,11 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) else val &= ~SC850SL_MIRROR_MASK; ret |= sc850sl_write_reg(sc850sl->client, SC850SL_FLIP_REG, - SC850SL_REG_VALUE_08BIT, val); + SC850SL_REG_VALUE_08BIT, val); break; case V4L2_CID_VFLIP: ret = sc850sl_read_reg(sc850sl->client, SC850SL_FLIP_REG, - SC850SL_REG_VALUE_08BIT, &val); + SC850SL_REG_VALUE_08BIT, &val); if (ret) break; if (ctrl->val) @@ -1713,7 +1721,7 @@ static int sc850sl_set_ctrl(struct v4l2_ctrl *ctrl) else val &= ~SC850SL_FLIP_MASK; ret |= sc850sl_write_reg(sc850sl->client, SC850SL_FLIP_REG, - SC850SL_REG_VALUE_08BIT, val); + SC850SL_REG_VALUE_08BIT, val); break; default: dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", @@ -1748,37 +1756,37 @@ static int sc850sl_initialize_controls(struct sc850sl *sc850sl) handler->lock = &sc850sl->mutex; sc850sl->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, - V4L2_CID_LINK_FREQ, 0, 0, link_freq_items); + V4L2_CID_LINK_FREQ, 0, 0, link_freq_items); v4l2_ctrl_s_ctrl(sc850sl->link_freq, mode->mipi_freq_idx); /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC850SL_4LANES; sc850sl->pixel_rate = v4l2_ctrl_new_std(handler, NULL, - V4L2_CID_PIXEL_RATE, 0, SC850SL_MAX_PIXEL_RATE, - 1, pixel_rate); + V4L2_CID_PIXEL_RATE, 0, SC850SL_MAX_PIXEL_RATE, + 1, pixel_rate); h_blank = mode->hts_def - mode->width; sc850sl->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, - h_blank, h_blank, 1, h_blank); + h_blank, h_blank, 1, h_blank); if (sc850sl->hblank) sc850sl->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; vblank_def = mode->vts_def - mode->height; sc850sl->vblank = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops, - V4L2_CID_VBLANK, vblank_def, - SC850SL_VTS_MAX - mode->height, - 1, vblank_def); + V4L2_CID_VBLANK, vblank_def, + SC850SL_VTS_MAX - mode->height, + 1, vblank_def); - exposure_max = mode->vts_def - 4; /*vts_def 0x08ca=2250*/ - sc850sl->exposure = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops, - V4L2_CID_EXPOSURE, SC850SL_EXPOSURE_MIN, - exposure_max, SC850SL_EXPOSURE_STEP, - mode->exp_def); /*exp_def 0x08c0=2240*/ + exposure_max = mode->vts_def - 4; /*vts_def 0x08ca=2250*/ + sc850sl->exposure = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops, + V4L2_CID_EXPOSURE, SC850SL_EXPOSURE_MIN, + exposure_max, SC850SL_EXPOSURE_STEP, + mode->exp_def); /*exp_def 0x08c0=2240*/ sc850sl->anal_a_gain = v4l2_ctrl_new_std(handler, &sc850sl_ctrl_ops, - V4L2_CID_ANALOGUE_GAIN, SC850SL_GAIN_MIN, - SC850SL_GAIN_MAX, SC850SL_GAIN_STEP, - SC850SL_GAIN_DEFAULT); + V4L2_CID_ANALOGUE_GAIN, SC850SL_GAIN_MIN, + SC850SL_GAIN_MAX, SC850SL_GAIN_STEP, + SC850SL_GAIN_DEFAULT); sc850sl->test_pattern = v4l2_ctrl_new_std_menu_items(handler, &sc850sl_ctrl_ops, V4L2_CID_TEST_PATTERN, @@ -1791,12 +1799,13 @@ static int sc850sl_initialize_controls(struct sc850sl *sc850sl) if (handler->error) { ret = handler->error; dev_err(&sc850sl->client->dev, - "Failed to init controls(%d)\n", ret); + "Failed to init controls(%d)\n", ret); goto err_free_handler; } sc850sl->subdev.ctrl_handler = handler; sc850sl->has_init_exp = false; + sc850sl->is_standby = false; sc850sl->cur_fps = mode->max_fps; sc850sl->cur_vts = mode->vts_def; @@ -1809,7 +1818,7 @@ err_free_handler: } static int sc850sl_check_sensor_id(struct sc850sl *sc850sl, - struct i2c_client *client) + struct i2c_client *client) { struct device *dev = &sc850sl->client->dev; u32 id = 0; @@ -1820,7 +1829,7 @@ static int sc850sl_check_sensor_id(struct sc850sl *sc850sl, return 0; } ret = sc850sl_read_reg(client, SC850SL_REG_CHIP_ID, - SC850SL_REG_VALUE_16BIT, &id); + SC850SL_REG_VALUE_16BIT, &id); if (id != CHIP_ID) { dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret); return -ENODEV; @@ -1844,7 +1853,7 @@ static int sc850sl_configure_regulators(struct sc850sl *sc850sl) } static int sc850sl_probe(struct i2c_client *client, - const struct i2c_device_id *id) + const struct i2c_device_id *id) { struct device *dev = &client->dev; struct device_node *node = dev->of_node; @@ -1855,9 +1864,9 @@ static int sc850sl_probe(struct i2c_client *client, u32 i, hdr_mode = 0; dev_info(dev, "driver version: %02x.%02x.%02x", - DRIVER_VERSION >> 16, - (DRIVER_VERSION & 0xff00) >> 8, - DRIVER_VERSION & 0x00ff); + DRIVER_VERSION >> 16, + (DRIVER_VERSION & 0xff00) >> 8, + DRIVER_VERSION & 0x00ff); sc850sl = devm_kzalloc(dev, sizeof(*sc850sl), GFP_KERNEL); if (!sc850sl) @@ -1876,6 +1885,10 @@ static int sc850sl_probe(struct i2c_client *client, return -EINVAL; } + /* Compatible with non-standby mode if this attribute is not configured in dts*/ + of_property_read_u32(node, RKMODULE_CAMERA_STANDBY_HW, + &sc850sl->standby_hw); + ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode); if (ret) { hdr_mode = NO_HDR; @@ -1899,12 +1912,12 @@ static int sc850sl_probe(struct i2c_client *client, } sc850sl->reset_gpio = devm_gpiod_get(dev, "reset", - sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW); + sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW); if (IS_ERR(sc850sl->reset_gpio)) dev_warn(dev, "Failed to get reset-gpios\n"); sc850sl->pwdn_gpio = devm_gpiod_get(dev, "pwdn", - sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW); + sc850sl->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW); if (IS_ERR(sc850sl->pwdn_gpio)) dev_warn(dev, "Failed to get pwdn_gpio\n"); diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 8f19b4ad44db..dd4cf893139e 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -5411,6 +5411,7 @@ static void rkcif_stream_stop(struct rkcif_stream *stream) int i = 0; int ret = 0; + atomic_dec_if_positive(&stream->cifdev->id_use_cnt); if (cif_dev->switch_info.is_use_switch) { ret = atomic_dec_if_positive(&cif_dev->hw_dev->switch_stream_cnt[cif_dev->switch_info.host_idx]); if (ret) { @@ -5420,8 +5421,6 @@ static void rkcif_stream_stop(struct rkcif_stream *stream) } } - atomic_dec_if_positive(&stream->cifdev->id_use_cnt); - if (mbus_cfg->type == V4L2_MBUS_CSI2_DPHY || mbus_cfg->type == V4L2_MBUS_CSI2_CPHY || mbus_cfg->type == V4L2_MBUS_CCP2) { @@ -14257,7 +14256,8 @@ static int rkcif_terminal_sensor_set_stream(struct rkcif_device *cif_dev, int on rkcif_set_sof(cif_dev, cif_dev->stream[0].frame_idx); if (p->subdevs[i] == terminal_sensor->sd && (cif_dev->chip_id == CHIP_RV1106_CIF || - cif_dev->chip_id == CHIP_RV1103B_CIF)) { + cif_dev->chip_id == CHIP_RV1103B_CIF || + cif_dev->chip_id == CHIP_RV1126B_CIF)) { if (!rk_tb_mcu_is_done() && on) { cif_dev->tb_client.data = p->subdevs[i]; cif_dev->tb_client.cb = rkcif_sensor_quick_streaming_cb; diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c index e28a0a0de2ae..0defdbc3ff59 100644 --- a/drivers/thermal/rockchip_thermal.c +++ b/drivers/thermal/rockchip_thermal.c @@ -337,16 +337,13 @@ struct rockchip_thermal_data { #define RV1126B_GRF_TSADC_CON1 0x54 #define RV1126B_GRF_TSADC_CON6 0x68 #define RV1126B_GRF_TSADC_ST1 0x114 -#define RV1126B_CH_EN 0x300 -#define RV1126B_CH_EN_MASK (0x300 << 16) #define RV1126B_UNLOCK_VALUE 0xa5 #define RV1126B_UNLOCK_VALUE_MASK (0xff << 16) #define RV1126B_UNLOCK_TRIGGER BIT(8) #define RV1126B_UNLOCK_TRIGGER_MASK (BIT(8) << 16) #define RV1126B_MAX_BIAS 0x7f #define RV1126B_BIAS_MASK (0x7f << 16) -#define RV1126B_SW_CTRL 0x8028 -#define RV1126B_SW_CTRL_MASK (0x8078 << 16) +#define RV1126B_CTRL_MASK (0x8078 << 16) #define GRF_SARADC_TESTBIT_ON (0x10001 << 2) #define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) @@ -1409,13 +1406,7 @@ static int rk_tsadcv5_get_temp(const struct chip_tsadc_table *table, { u32 val; - if (chn == 0) - val = readl_relaxed(regs + TSADCV3_DATA(1)); - else if (chn == 1) - val = readl_relaxed(regs + TSADCV3_DATA(0)); - else - return -EINVAL; - + val = readl_relaxed(regs + TSADCV3_DATA(chn)); *temp = val & TSADCV6_DATA_MASK; if (val & TSADC_DATA_SIGN_BIT) *temp |= TSADC_DATA_NEGATIVE; @@ -1698,10 +1689,7 @@ static void rv1126b_tsadc_phy_init(struct device *dev, struct regmap *grf, } regmap_read(grf, RV1126B_GRF_TSADC_ST1, &val); dev_info(dev, "width=0x%x, bias=0x%x\n", val, phy_cfg->bias); - regmap_write(grf, RV1126B_GRF_TSADC_CON6, - RV1126B_CH_EN | RV1126B_CH_EN_MASK); - regmap_write(grf, RV1126B_GRF_TSADC_CON0, - RV1126B_SW_CTRL | RV1126B_SW_CTRL_MASK); + regmap_write(grf, RV1126B_GRF_TSADC_CON0, RV1126B_CTRL_MASK); regmap_write(grf, RV1126B_GRF_TSADC_CON1, RV1126B_UNLOCK_VALUE | RV1126B_UNLOCK_VALUE_MASK); regmap_write(grf, RV1126B_GRF_TSADC_CON1, @@ -1829,8 +1817,8 @@ static const struct rockchip_tsadc_chip rv1126_tsadc_data = { }; static const struct rockchip_tsadc_chip rv1126b_tsadc_data = { - .chn_id = {0, 1}, /* cpu, npu */ - .chn_num = 2, /* two channels for tsadc */ + .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + .chn_num = 1, /* one channel for tsadc */ .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ .tshut_temp = 95000, diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 9bc05d21639a..61abd0cb6875 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -33,6 +33,10 @@ #include #include +#ifdef CONFIG_PM_DEVFREQ +#include "../../../devfreq/governor.h" +#endif + #include "mpp_debug.h" #include "mpp_iommu.h" #include "mpp_common.h" @@ -53,6 +57,10 @@ #define to_rkvenc_dev(dev) \ container_of(dev, struct rkvenc_dev, mpp) +#ifdef CONFIG_PM_DEVFREQ +static DEFINE_MUTEX(venc_governor_mutex); +static int venc_governor_count; +#endif enum RKVENC_FORMAT_TYPE { RKVENC_FMT_BASE = 0x0000, @@ -328,6 +336,9 @@ struct rkvenc_dev { u32 bs_overflow; #ifdef CONFIG_PM_DEVFREQ + struct devfreq *devfreq; + unsigned long core_rate_hz; + unsigned long core_current_rate_hz; struct rockchip_opp_info opp_info; struct monitor_dev_info *mdev_info; #endif @@ -2127,6 +2138,90 @@ static inline int rkvenc_procfs_ccu_init(struct mpp_dev *mpp) #endif #ifdef CONFIG_PM_DEVFREQ +static int rkvenc_devfreq_target(struct device *dev, + unsigned long *freq, u32 flags) +{ + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); + struct devfreq *devfreq = enc->devfreq; + struct rockchip_opp_info *opp_info = &enc->opp_info; + struct dev_pm_opp *opp; + int ret = 0; + + if (!opp_info->is_rate_volt_checked) + return -EINVAL; + + opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(opp)) + return PTR_ERR(opp); + dev_pm_opp_put(opp); + + if (*freq == enc->core_current_rate_hz) + return 0; + + rockchip_opp_dvfs_lock(opp_info); + if (pm_runtime_active(dev)) + opp_info->is_runtime_active = true; + else + opp_info->is_runtime_active = false; + ret = dev_pm_opp_set_rate(dev, *freq); + if (!ret) { + enc->core_current_rate_hz = *freq; + devfreq->last_status.current_frequency = *freq; + } + rockchip_opp_dvfs_unlock(opp_info); + + return ret; +} + +static int rkvenc_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +{ + return 0; +} + +static int rkvenc_devfreq_get_cur_freq(struct device *dev, + unsigned long *freq) +{ + struct mpp_dev *mpp = dev_get_drvdata(dev); + struct rkvenc_dev *enc = to_rkvenc_dev(mpp); + + *freq = enc->core_current_rate_hz; + + return 0; +} + +static struct devfreq_dev_profile rkvenc_devfreq_profile = { + .target = rkvenc_devfreq_target, + .get_dev_status = rkvenc_devfreq_get_dev_status, + .get_cur_freq = rkvenc_devfreq_get_cur_freq, + .is_cooling_device = true, +}; + +static int devfreq_venc_ondemand_func(struct devfreq *df, unsigned long *freq) +{ + struct rkvenc_dev *enc = df->data; + + if (enc) + *freq = enc->core_rate_hz; + else + *freq = df->previous_freq; + + return 0; +} + +static int devfreq_venc_ondemand_handler(struct devfreq *devfreq, + unsigned int event, void *data) +{ + return 0; +} + +static struct devfreq_governor devfreq_venc_ondemand = { + .name = "venc_ondemand", + .get_target_freq = devfreq_venc_ondemand_func, + .event_handler = devfreq_venc_ondemand_handler, +}; + static int rk3588_venc_set_read_margin(struct device *dev, struct rockchip_opp_info *opp_info, u32 rm) @@ -2164,6 +2259,8 @@ static const struct of_device_id rockchip_rkvenc_of_match[] = { static struct monitor_dev_profile venc_mdevp = { .type = MONITOR_TYPE_DEV, .check_rate_volt = rockchip_monitor_check_rate_volt, + .low_temp_adjust = rockchip_monitor_dev_low_temp_adjust, + .high_temp_adjust = rockchip_monitor_dev_high_temp_adjust, }; static int rkvenc_devfreq_init(struct mpp_dev *mpp) @@ -2183,6 +2280,33 @@ static int rkvenc_devfreq_init(struct mpp_dev *mpp) dev_err(dev, "failed to init_opp_table\n"); return ret; } + + mutex_lock(&venc_governor_mutex); + if (!venc_governor_count) { + ret = devfreq_add_governor(&devfreq_venc_ondemand); + if (ret) { + dev_err(dev, "failed to add venc_ondemand governor\n"); + mutex_unlock(&venc_governor_mutex); + goto governor_err; + } + } + venc_governor_count++; + mutex_unlock(&venc_governor_mutex); + + rkvenc_devfreq_profile.initial_freq = clk_get_rate(clk_core); + enc->core_rate_hz = rkvenc_devfreq_profile.initial_freq; + enc->devfreq = devm_devfreq_add_device(dev, + &rkvenc_devfreq_profile, + "venc_ondemand", (void *)enc); + if (IS_ERR(enc->devfreq)) { + ret = PTR_ERR(enc->devfreq); + enc->devfreq = NULL; + goto devfreq_err; + } + + devfreq_register_opp_notifier(dev, enc->devfreq); + + venc_mdevp.data = enc->devfreq; venc_mdevp.opp_info = opp_info; enc->mdev_info = rockchip_system_monitor_register(dev, &venc_mdevp); if (IS_ERR(enc->mdev_info)) { @@ -2190,6 +2314,24 @@ static int rkvenc_devfreq_init(struct mpp_dev *mpp) enc->mdev_info = NULL; } + enc->core_current_rate_hz = clk_get_rate(clk_core); + enc->core_rate_hz = enc->core_current_rate_hz; + if (enc->devfreq->suspend_freq) + enc->devfreq->resume_freq = enc->core_current_rate_hz; + enc->devfreq->last_status.current_frequency = enc->core_current_rate_hz; + enc->devfreq->last_status.total_time = 1; + enc->devfreq->last_status.busy_time = 1; + + return 0; + +devfreq_err: + mutex_lock(&venc_governor_mutex); + if (--venc_governor_count == 0) + devfreq_remove_governor(&devfreq_venc_ondemand); + mutex_unlock(&venc_governor_mutex); +governor_err: + dev_pm_opp_of_remove_table(dev); + return ret; } @@ -2201,6 +2343,12 @@ static int rkvenc_devfreq_remove(struct mpp_dev *mpp) rockchip_system_monitor_unregister(enc->mdev_info); enc->mdev_info = NULL; } + if (enc->devfreq) + devfreq_unregister_opp_notifier(mpp->dev, enc->devfreq); + mutex_lock(&venc_governor_mutex); + if (--venc_governor_count == 0) + devfreq_remove_governor(&devfreq_venc_ondemand); + mutex_unlock(&venc_governor_mutex); rockchip_uninit_opp_table(mpp->dev, &enc->opp_info); return 0; @@ -2297,6 +2445,10 @@ static int rkvenc_reset(struct mpp_dev *mpp) mpp_debug_enter(); +#ifdef CONFIG_PM_DEVFREQ + if (enc->devfreq) + mutex_lock(&enc->devfreq->lock); +#endif /* safe reset first*/ ret = rkvenc_soft_reset(mpp); @@ -2325,6 +2477,11 @@ static int rkvenc_reset(struct mpp_dev *mpp) mpp_dbg_core("core %d reset idle %lx\n", mpp->core_id, queue->core_idle); +#ifdef CONFIG_PM_DEVFREQ + if (enc->devfreq) + mutex_unlock(&enc->devfreq->lock); +#endif + mpp_debug_leave(); return 0; @@ -2358,6 +2515,27 @@ static int rkvenc_set_freq(struct mpp_dev *mpp, struct mpp_task *mpp_task) struct rkvenc_task *task = to_rkvenc_task(mpp_task); mpp_clk_set_rate(&enc->aclk_info, task->clk_mode); + +#ifdef CONFIG_PM_DEVFREQ + if (enc->devfreq) { + unsigned long core_rate_hz; + + mutex_lock(&enc->devfreq->lock); + core_rate_hz = mpp_get_clk_info_rate_hz(&enc->core_clk_info, task->clk_mode); + if (enc->core_rate_hz != core_rate_hz) { + enc->core_rate_hz = core_rate_hz; + update_devfreq(enc->devfreq); + } else { + /* + * Restore frequency when frequency is changed by + * rkvenc_reduce_freq() + */ + clk_set_rate(enc->core_clk_info.clk, enc->core_current_rate_hz); + } + mutex_unlock(&enc->devfreq->lock); + return 0; + } +#endif mpp_clk_set_rate(&enc->core_clk_info, task->clk_mode); return 0; diff --git a/drivers/video/rockchip/mpp_osal/mpp_osal.c b/drivers/video/rockchip/mpp_osal/mpp_osal.c index abdaf4be6a22..4c3f1297ba57 100644 --- a/drivers/video/rockchip/mpp_osal/mpp_osal.c +++ b/drivers/video/rockchip/mpp_osal/mpp_osal.c @@ -41,3 +41,13 @@ void mpp_device_add_driver(void *dev, void *drv) #endif } EXPORT_SYMBOL(mpp_device_add_driver); + +struct dma_iommu_mapping *mpp_arm_iommu_get_mapping(struct device *dev) +{ +#ifdef CONFIG_ARM_DMA_USE_IOMMU + return dev->archdata.mapping; +#else + return NULL; +#endif +} +EXPORT_SYMBOL(mpp_arm_iommu_get_mapping); diff --git a/drivers/video/rockchip/mpp_osal/mpp_osal.h b/drivers/video/rockchip/mpp_osal/mpp_osal.h index 826f006d8552..7082acd308f4 100644 --- a/drivers/video/rockchip/mpp_osal/mpp_osal.h +++ b/drivers/video/rockchip/mpp_osal/mpp_osal.h @@ -10,10 +10,13 @@ #include #include +struct dma_iommu_mapping; + struct device_node *mpp_dev_of_node(struct device *dev); void mpp_pm_relax(struct device *dev); void mpp_pm_stay_awake(struct device *dev); int mpp_device_init_wakeup(struct device *dev, bool enable); void mpp_device_add_driver(void *dev, void *drv); +struct dma_iommu_mapping *mpp_arm_iommu_get_mapping(struct device *dev); #endif