diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml index 6d78048c4613..f7710ac52fef 100644 --- a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -222,6 +222,11 @@ properties: When set, all SuperSpeed bus instances in park mode are disabled. type: boolean + snps,parkmode-disable-hs-quirk: + description: + When set, all HighSpeed bus instances in park mode are disabled. + type: boolean + snps,dis_metastability_quirk: description: When set, disable metastability workaround. CAUTION! Use only if you are diff --git a/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts b/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts index 50f1e8134db8..68a3ed7cb837 100644 --- a/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts +++ b/arch/arm/boot/dts/rk3288-evb-rk808-linux.dts @@ -1,42 +1,4 @@ -/* - * This file is dual-licensed: you can use it either under the terms - * of the GPL or the X11 license, at your option. Note that this dual - * licensing only applies to this file, and not this project as a - * whole. - * - * a) This file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * Or, alternatively, - * - * b) Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /dts-v1/; #include "rk3288-evb.dtsi" @@ -262,7 +224,8 @@ regulator-max-microvolt = <3300000>; regulator-name = "vcca_codec"; regulator-state-mem { - regulator-off-in-suspend; + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; }; }; @@ -282,10 +245,10 @@ regulator-always-on; regulator-boot-on; regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-max-microvolt = <1800000>; regulator-name = "vcc_wl"; regulator-state-mem { - regulator-off-in-suspend; + regulator-on-in-suspend; }; }; @@ -296,8 +259,7 @@ regulator-max-microvolt = <3300000>; regulator-name = "vccio_sd"; regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; + regulator-off-in-suspend; }; }; @@ -340,7 +302,7 @@ regulator-boot-on; regulator-name = "vcc_sd"; regulator-state-mem { - regulator-on-in-suspend; + regulator-off-in-suspend; }; }; diff --git a/arch/arm/boot/dts/rk3288-linux.dtsi b/arch/arm/boot/dts/rk3288-linux.dtsi index 8262a19d8b52..1ea066a70977 100644 --- a/arch/arm/boot/dts/rk3288-linux.dtsi +++ b/arch/arm/boot/dts/rk3288-linux.dtsi @@ -7,6 +7,13 @@ #include "rk3288-dram-default-timing.dtsi" / { + aliases { + mshc0 = &emmc; + mshc1 = &sdmmc; + mshc2 = &sdio0; + mshc3 = &sdio1; + }; + chosen { bootargs = "earlycon=uart8250,mmio32,0xff690000 console=ttyFIQ0 vmalloc=496M rw root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait"; }; diff --git a/arch/arm/configs/rockchip_linux_defconfig b/arch/arm/configs/rockchip_linux_defconfig index 3c22896cd8dd..d14d6a8de2ac 100644 --- a/arch/arm/configs/rockchip_linux_defconfig +++ b/arch/arm/configs/rockchip_linux_defconfig @@ -333,7 +333,9 @@ CONFIG_SND_SOC_ROCKCHIP=y CONFIG_SND_SOC_ROCKCHIP_SAI=y CONFIG_SND_SOC_ROCKCHIP_SPDIF=y CONFIG_SND_SOC_ROCKCHIP_MAX98090=y +CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=y CONFIG_SND_SOC_ROCKCHIP_RT5645=y +CONFIG_SND_SOC_ROCKCHIP_HDMI=y CONFIG_SND_SOC_ES8311=y CONFIG_SND_SOC_ES8323=y CONFIG_SND_SOC_ES8396=y diff --git a/arch/arm64/boot/dts/rockchip/rk1808.dtsi b/arch/arm64/boot/dts/rockchip/rk1808.dtsi index 429bbd657124..cf9f850b8e74 100644 --- a/arch/arm64/boot/dts/rockchip/rk1808.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk1808.dtsi @@ -378,7 +378,8 @@ phy-names = "usb2-phy", "usb3-phy"; phy_type = "utmi_wide"; snps,dis_enblslpm_quirk; - snps,dis-u1u2-quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; snps,dis-u2-freeclk-exists-quirk; snps,dis_u2_susphy_quirk; snps,dis_u3_susphy_quirk; diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi index 3f176b3bc94f..5ad85b1679f8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-npu.dtsi @@ -149,7 +149,8 @@ phy-names = "usb2-phy", "usb3-phy"; phy_type = "utmi_wide"; snps,dis_enblslpm_quirk; - snps,dis-u1u2-quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; snps,dis-u2-freeclk-exists-quirk; snps,dis_u2_susphy_quirk; snps,dis_u3_susphy_quirk; diff --git a/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/arch/arm64/boot/dts/rockchip/rk3528.dtsi index 9c62cd215527..50531e575220 100644 --- a/arch/arm64/boot/dts/rockchip/rk3528.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3528.dtsi @@ -644,7 +644,8 @@ resets = <&cru SRST_ARESETN_USB3OTG>; reset-names = "usb3-otg"; snps,dis_enblslpm_quirk; - snps,dis-u1u2-quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; snps,dis-u2-freeclk-exists-quirk; snps,dis-del-phy-power-chg-quirk; snps,dis-tx-ipgap-linecheck-quirk; diff --git a/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-camera.dtsi b/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-camera.dtsi index ac0586411d97..f2d5399c6a4f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-camera.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3562-rk817-tablet-camera.dtsi @@ -89,10 +89,11 @@ compatible = "dongwoon,dw9763"; status = "okay"; reg = <0x0c>; + avdd-supply = <&vcc2v8_dvp>; rockchip,vcm-max-current = <120>; - rockchip,vcm-start-current = <20>; - rockchip,vcm-rated-current = <90>; - rockchip,vcm-step-mode = <3>; + rockchip,vcm-start-current = <25>; + rockchip,vcm-rated-current = <100>; + rockchip,vcm-step-mode = <4>; rockchip,vcm-t-src = <0x20>; rockchip,vcm-t-div = <1>; rockchip,camera-module-index = <0>; diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi index eca37c90b301..3603c268182d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb3-lp5.dtsi @@ -67,7 +67,7 @@ fan: pwm-fan { compatible = "pwm-fan"; #cooling-cells = <2>; - pwms = <&pwm6 0 50000 0>; + pwms = <&pwm5 0 50000 0>; cooling-levels = <0 50 100 150 200 255>; rockchip,temp-trips = < 50000 1 @@ -815,20 +815,20 @@ }; }; -&hdmi1 { +&hdmi0 { enable-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; status = "okay"; }; -&hdmi1_in_vp0 { +&hdmi0_in_vp0 { status = "okay"; }; -&hdmi1_sound { +&hdmi0_sound { status = "okay"; }; -&hdptxphy_hdmi1 { +&hdptxphy_hdmi0 { status = "okay"; }; @@ -889,9 +889,9 @@ &i2c2 { status = "okay"; - usbc0: fusb302@22 { - compatible = "fcs,fusb302"; - reg = <0x22>; + usbc0: husb311@4e { + compatible = "hynetek,husb311"; + reg = <0x4e>; interrupt-parent = <&gpio0>; interrupts = ; pinctrl-names = "default"; @@ -1011,7 +1011,7 @@ }; }; -&i2s6_8ch { +&i2s5_8ch { status = "okay"; }; @@ -1138,8 +1138,8 @@ }; }; -&pwm6 { - pinctrl-0 = <&pwm6m1_pins>; +&pwm5 { + pinctrl-0 = <&pwm5m1_pins>; status = "okay"; }; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c index 20040bc5e5c2..2c5cb37c2892 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c @@ -2599,7 +2599,7 @@ static int dw_hdmi_connector_atomic_check(struct drm_connector *connector, hdmi_modb(hdmi, PKTSCHED_GCP_TX_EN, PKTSCHED_GCP_TX_EN, PKTSCHED_PKT_EN); mdelay(50); } else if (!hdmi->disabled) { - if (mode.clock > 600000) + if (hdmi->previous_mode.clock > 600000 && mode.clock > 600000) hdmi->frl_switch = true; hdmi->update = false; crtc_state->mode_changed = true; diff --git a/drivers/media/i2c/dw9763.c b/drivers/media/i2c/dw9763.c index 1a35b0e66887..d238f59da106 100644 --- a/drivers/media/i2c/dw9763.c +++ b/drivers/media/i2c/dw9763.c @@ -15,12 +15,14 @@ #include #include #include +#include -#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x0) +#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x1) #define DW9763_NAME "dw9763" #define DW9763_MAX_CURRENT 120U #define DW9763_MAX_REG 1023U +#define DW9763_GRADUAL_MOVELENS_STEPS 32 #define DW9763_DEFAULT_START_CURRENT 20 #define DW9763_DEFAULT_RATED_CURRENT 90 @@ -41,6 +43,10 @@ enum mode_e { DIRECT_MODE, }; +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "debug level (0-2)"); + /* dw9763 device structure */ struct dw9763_device { struct v4l2_ctrl_handler ctrls_vcm; @@ -69,6 +75,8 @@ struct dw9763_device { struct rk_cam_vcm_cfg vcm_cfg; int max_ma; struct mutex lock; + struct regulator *supply; + bool power_on; }; static inline struct dw9763_device *to_dw9763_vcm(struct v4l2_ctrl *ctrl) @@ -88,6 +96,7 @@ static int dw9763_write_reg(struct i2c_client *client, u8 reg, u8 buf[5]; u8 *val_p; __be32 val_be; + struct dw9763_device *dev_vcm = i2c_get_clientdata(client); if (len > 4) return -EINVAL; @@ -106,7 +115,7 @@ static int dw9763_write_reg(struct i2c_client *client, u8 reg, dev_err(&client->dev, "Failed to write 0x%04x,0x%x\n", reg, val); return -EIO; } - dev_dbg(&client->dev, "succeed to write 0x%04x,0x%x\n", reg, val); + v4l2_dbg(1, debug, &dev_vcm->sd, "succeed to write 0x%04x,0x%x\n", reg, val); return 0; } @@ -120,6 +129,7 @@ static int dw9763_read_reg(struct i2c_client *client, u8 *data_be_p; __be32 data_be = 0; int ret; + struct dw9763_device *dev_vcm = i2c_get_clientdata(client); if (len > 4 || !len) return -EINVAL; @@ -143,6 +153,8 @@ static int dw9763_read_reg(struct i2c_client *client, *val = be32_to_cpu(data_be); + v4l2_dbg(1, debug, &dev_vcm->sd, "succeed to read 0x%04x,0x%x\n", reg, *val); + return 0; } @@ -204,11 +216,11 @@ static unsigned int dw9763_move_time(struct dw9763_device *dev_vcm, break; } - dev_dbg(&client->dev, + v4l2_dbg(1, debug, &dev_vcm->sd, "%s: vcm_movefull_t is: %d us\n", __func__, move_time_us); - return move_time_us; + return ((move_time_us + 500) / 1000); } static int dw9763_set_dac(struct dw9763_device *dev_vcm, @@ -228,7 +240,7 @@ static int dw9763_set_dac(struct dw9763_device *dev_vcm, ret = dw9763_write_reg(client, 0x03, 2, dest_dac); if (ret != 0) goto err; - dev_dbg(&client->dev, + v4l2_dbg(1, debug, &dev_vcm->sd, "%s: set reg val %d\n", __func__, dest_dac); return ret; @@ -249,7 +261,7 @@ static int dw9763_get_dac(struct dw9763_device *dev_vcm, unsigned int *cur_dac) goto err; *cur_dac = abs_step; - dev_dbg(&client->dev, "%s: get dac %d\n", __func__, *cur_dac); + v4l2_dbg(1, debug, &dev_vcm->sd, "%s: get dac %d\n", __func__, *cur_dac); return 0; @@ -279,7 +291,7 @@ static int dw9763_get_pos(struct dw9763_device *dev_vcm, abs_step = 0; *cur_pos = abs_step; - dev_dbg(&client->dev, "%s: get position %d\n", __func__, *cur_pos); + v4l2_dbg(1, debug, &dev_vcm->sd, "%s: get position %d\n", __func__, *cur_pos); return 0; err: @@ -293,7 +305,6 @@ static int dw9763_set_pos(struct dw9763_device *dev_vcm, { int ret; unsigned int position = 0; - struct i2c_client *client = dev_vcm->client; if (dest_pos >= VCMDRV_MAX_LOG) position = dev_vcm->start_current; @@ -308,7 +319,8 @@ static int dw9763_set_pos(struct dw9763_device *dev_vcm, dev_vcm->current_related_pos = dest_pos; ret = dw9763_set_dac(dev_vcm, position); - dev_dbg(&client->dev, "%s: set position %d, dac %d\n", __func__, dest_pos, position); + v4l2_dbg(1, debug, &dev_vcm->sd, "%s: set position %d, dac %d\n", + __func__, dest_pos, position); return ret; } @@ -331,7 +343,7 @@ static int dw9763_set_ctrl(struct v4l2_ctrl *ctrl) long mv_us; int ret = 0; - dev_dbg(&client->dev, "ctrl->id: 0x%x, ctrl->val: 0x%x\n", + v4l2_dbg(1, debug, &dev_vcm->sd, "ctrl->id: 0x%x, ctrl->val: 0x%x\n", ctrl->id, ctrl->val); if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) { @@ -345,9 +357,9 @@ static int dw9763_set_ctrl(struct v4l2_ctrl *ctrl) ret = dw9763_set_pos(dev_vcm, dest_pos); - dev_vcm->move_us = dev_vcm->vcm_movefull_t; + dev_vcm->move_us = dev_vcm->vcm_movefull_t * 1000; - dev_dbg(&client->dev, + v4l2_dbg(1, debug, &dev_vcm->sd, "dest_pos %d, move_us %ld\n", dest_pos, dev_vcm->move_us); @@ -373,9 +385,19 @@ static const struct v4l2_ctrl_ops dw9763_vcm_ctrl_ops = { .s_ctrl = dw9763_set_ctrl, }; +static int dw9763_init(struct i2c_client *client); static int dw9763_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { int rval; + struct dw9763_device *dev_vcm = sd_to_dw9763_vcm(sd); + unsigned int move_time; + int dac = dev_vcm->start_current; + struct i2c_client *client = dev_vcm->client; + +#ifdef CONFIG_PM + v4l2_info(sd, "%s: enter, power.usage_count(%d)!\n", __func__, + atomic_read(&sd->dev->power.usage_count)); +#endif rval = pm_runtime_get_sync(sd->dev); if (rval < 0) { @@ -383,12 +405,72 @@ static int dw9763_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return rval; } + dw9763_init(client); + + v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n", + __func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos); + + move_time = 1000 * dw9763_move_time(dev_vcm, DW9763_GRADUAL_MOVELENS_STEPS); + while (dac <= dev_vcm->current_lens_pos) { + dw9763_set_dac(dev_vcm, dac); + usleep_range(move_time, move_time + 100); + dac += DW9763_GRADUAL_MOVELENS_STEPS; + if (dac > dev_vcm->current_lens_pos) + break; + } + + if (dac > dev_vcm->current_lens_pos) { + dac = dev_vcm->current_lens_pos; + dw9763_set_dac(dev_vcm, dac); + } + +#ifdef CONFIG_PM + v4l2_info(sd, "%s: exit, power.usage_count(%d)!\n", __func__, + atomic_read(&sd->dev->power.usage_count)); +#endif return 0; } static int dw9763_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + struct dw9763_device *dev_vcm = sd_to_dw9763_vcm(sd); + int dac = dev_vcm->current_lens_pos; + unsigned int move_time; + int ret; + struct i2c_client *client = dev_vcm->client; + +#ifdef CONFIG_PM + v4l2_info(sd, "%s: enter, power.usage_count(%d)!\n", __func__, + atomic_read(&sd->dev->power.usage_count)); +#endif + + v4l2_dbg(1, debug, sd, "%s: current_lens_pos %d, current_related_pos %d\n", + __func__, dev_vcm->current_lens_pos, dev_vcm->current_related_pos); + + dac -= DW9763_GRADUAL_MOVELENS_STEPS; + move_time = 1000 * dw9763_move_time(dev_vcm, DW9763_GRADUAL_MOVELENS_STEPS); + while (dac >= DW9763_GRADUAL_MOVELENS_STEPS) { + dw9763_set_dac(dev_vcm, dac); + usleep_range(move_time, move_time + 1000); + dac -= DW9763_GRADUAL_MOVELENS_STEPS; + if (dac <= 0) + break; + } + + if (dac < DW9763_GRADUAL_MOVELENS_STEPS) { + dac = DW9763_GRADUAL_MOVELENS_STEPS / 2; + dw9763_set_dac(dev_vcm, dac); + } + /* set to power down mode */ + ret = dw9763_write_reg(client, 0x02, 1, 0x01); + if (ret) + dev_err(&client->dev, "failed to set power down mode!\n"); + pm_runtime_put(sd->dev); +#ifdef CONFIG_PM + v4l2_info(sd, "%s: exit, power.usage_count(%d)!\n", __func__, + atomic_read(&sd->dev->power.usage_count)); +#endif return 0; } @@ -442,7 +524,7 @@ static long dw9763_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) vcm_tim->vcm_end_t.tv_sec = dev_vcm->end_move_tv.tv_sec; vcm_tim->vcm_end_t.tv_usec = dev_vcm->end_move_tv.tv_usec; - dev_dbg(&client->dev, "dw9763_get_move_res 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", + v4l2_dbg(1, debug, &dev_vcm->sd, "dw9763_get_move_res 0x%lx, 0x%lx, 0x%lx, 0x%lx\n", vcm_tim->vcm_start_t.tv_sec, vcm_tim->vcm_start_t.tv_usec, vcm_tim->vcm_end_t.tv_sec, @@ -634,13 +716,50 @@ static inline int remove_sysfs_interfaces(struct device *dev) } #endif -static int __dw9763_set_power(struct dw9763_device *dw9763_dev, bool on) +static int __dw9763_set_power(struct dw9763_device *dw9763, bool on) { - if (dw9763_dev->power_gpio) - gpiod_direction_output(dw9763_dev->power_gpio, on); - usleep_range(10000, 11000); + struct i2c_client *client = dw9763->client; + int ret = 0; - return 0; + dev_info(&client->dev, "%s(%d) on(%d)\n", __func__, __LINE__, on); + + if (dw9763->power_on == !!on) + goto unlock_and_return; + + if (on) { + ret = regulator_enable(dw9763->supply); + if (ret < 0) { + dev_err(&client->dev, "Failed to enable regulator\n"); + goto unlock_and_return; + } + dw9763->power_on = true; + } else { + ret = regulator_disable(dw9763->supply); + if (ret < 0) { + dev_err(&client->dev, "Failed to disable regulator\n"); + goto unlock_and_return; + } + dw9763->power_on = false; + } + +unlock_and_return: + return ret; +} + +static int dw9763_configure_regulator(struct dw9763_device *dw9763) +{ + struct i2c_client *client = dw9763->client; + int ret = 0; + + dw9763->supply = devm_regulator_get(&client->dev, "avdd"); + if (IS_ERR(dw9763->supply)) { + ret = PTR_ERR(dw9763->supply); + if (ret != -EPROBE_DEFER) + dev_err(&client->dev, "could not get regulator avdd\n"); + return ret; + } + dw9763->power_on = false; + return ret; } static int __maybe_unused dw9763_check_id(struct dw9763_device *dw9763_dev) @@ -662,20 +781,6 @@ static int __maybe_unused dw9763_check_id(struct dw9763_device *dw9763_dev) "Detected dw9763 vcm id:0x%x\n", DW9763_CHIP_ID); return 0; } -static int dw9763_probe_init(struct i2c_client *client) -{ - int ret = 0; - - /* Default goto power down mode when finished probe */ - ret = dw9763_write_reg(client, 0x02, 1, 0x01); - if (ret) - goto err; - - return 0; -err: - dev_err(&client->dev, "probe init failed with error %d\n", ret); - return -1; -} static int dw9763_probe(struct i2c_client *client, const struct i2c_device_id *id) @@ -765,9 +870,11 @@ static int dw9763_probe(struct i2c_client *client, dev_warn(&client->dev, "Failed to get power-gpios, maybe no use\n"); } - - /* enter power down mode */ - dw9763_probe_init(client); + ret = dw9763_configure_regulator(dw9763_dev); + if (ret) { + dev_err(&client->dev, "Failed to get power regulator!\n"); + return ret; + } v4l2_i2c_subdev_init(&dw9763_dev->sd, client, &dw9763_ops); dw9763_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; @@ -781,6 +888,10 @@ static int dw9763_probe(struct i2c_client *client, if (ret < 0) goto err_cleanup; + ret = dw9763_check_id(dw9763_dev); + if (ret) + goto err_power_off; + sd = &dw9763_dev->sd; sd->entity.function = MEDIA_ENT_F_LENS; @@ -823,6 +934,9 @@ static int dw9763_probe(struct i2c_client *client, dev_info(&client->dev, "probing successful\n"); return 0; +err_power_off: + __dw9763_set_power(dw9763_dev, false); + err_cleanup: dw9763_subdev_cleanup(dw9763_dev); @@ -845,21 +959,18 @@ static int dw9763_init(struct i2c_client *client) { struct dw9763_device *dev_vcm = i2c_get_clientdata(client); int ret = 0; - u32 ring = 0; u32 mode_val = 0; u32 algo_time = 0; + if (dev_vcm->step_mode == DIRECT_MODE) + return 0; - /* Delay 200us~300us */ - usleep_range(200, 300); ret = dw9763_write_reg(client, 0x02, 1, 0x00); if (ret) goto err; - usleep_range(100, 200); - if (dev_vcm->step_mode != DIRECT_MODE) - ring = 0x02; - ret = dw9763_write_reg(client, 0x02, 1, ring); + usleep_range(200, 300); + ret = dw9763_write_reg(client, 0x02, 1, 0x02); if (ret) goto err; switch (dev_vcm->step_mode) { @@ -893,13 +1004,15 @@ err: static int __maybe_unused dw9763_vcm_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - int ret = 0; + struct dw9763_device *dev_vcm = i2c_get_clientdata(client); + struct v4l2_subdev *sd = &(dev_vcm->sd); - /* set to power down mode */ - ret = dw9763_write_reg(client, 0x02, 1, 0x01); - if (ret) - dev_err(&client->dev, "failed to set power down mode!\n"); +#ifdef CONFIG_PM + v4l2_dbg(1, debug, sd, "%s: enter, power.usage_count(%d)!\n", __func__, + atomic_read(&sd->dev->power.usage_count)); +#endif + __dw9763_set_power(dev_vcm, false); return 0; } @@ -907,9 +1020,14 @@ static int __maybe_unused dw9763_vcm_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct dw9763_device *dev_vcm = i2c_get_clientdata(client); + struct v4l2_subdev *sd = &(dev_vcm->sd); + +#ifdef CONFIG_PM + v4l2_dbg(1, debug, sd, "%s: enter, power.usage_count(%d)!\n", __func__, + atomic_read(&sd->dev->power.usage_count)); +#endif + __dw9763_set_power(dev_vcm, true); - dw9763_init(client); - dw9763_set_pos(dev_vcm, dev_vcm->current_related_pos); return 0; } diff --git a/drivers/media/platform/rockchip/isp/capture_v21.c b/drivers/media/platform/rockchip/isp/capture_v21.c index a5a4053eca83..37ba5f66110c 100644 --- a/drivers/media/platform/rockchip/isp/capture_v21.c +++ b/drivers/media/platform/rockchip/isp/capture_v21.c @@ -1206,6 +1206,9 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) unsigned long lock_flags = 0; int i = 0; + if (stream->id == RKISP_STREAM_VIR) + return 0; + if (!stream->next_buf && stream->streaming && dev->dmarx_dev.trigger == T_MANUAL && is_rdbk_stream(stream)) @@ -1218,6 +1221,7 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) (!interlaced || (stream->u.sp.field_rec == RKISP_FIELD_ODD && stream->u.sp.field == RKISP_FIELD_EVEN))) { + struct rkisp_stream *vir = &dev->cap_dev.stream[RKISP_STREAM_VIR]; struct vb2_buffer *vb2_buf = &stream->curr_buf->vb.vb2_buf; u64 ns = 0; @@ -1268,7 +1272,16 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) rdbk_frame_end(stream); } } else { - rkisp_stream_buf_done(stream, stream->curr_buf); + if (vir->streaming && vir->conn_id == stream->id) { + spin_lock_irqsave(&vir->vbq_lock, lock_flags); + list_add_tail(&stream->curr_buf->queue, + &dev->cap_dev.vir_cpy.queue); + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); + if (!completion_done(&dev->cap_dev.vir_cpy.cmpl)) + complete(&dev->cap_dev.vir_cpy.cmpl); + } else { + rkisp_stream_buf_done(stream, stream->curr_buf); + } } stream->curr_buf = NULL; @@ -1379,6 +1392,98 @@ static void rkisp_stream_stop(struct rkisp_stream *stream) stream->interlaced = false; } +static void vir_cpy_image(struct work_struct *work) +{ + struct rkisp_vir_cpy *cpy = + container_of(work, struct rkisp_vir_cpy, work); + struct rkisp_stream *vir = cpy->stream; + struct rkisp_buffer *src_buf = NULL; + unsigned long lock_flags = 0; + u32 i; + + v4l2_dbg(1, rkisp_debug, &vir->ispdev->v4l2_dev, + "%s enter\n", __func__); + + vir->streaming = true; + spin_lock_irqsave(&vir->vbq_lock, lock_flags); + if (!list_empty(&cpy->queue)) { + src_buf = list_first_entry(&cpy->queue, + struct rkisp_buffer, queue); + list_del(&src_buf->queue); + } + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); + + while (src_buf || vir->streaming) { + if (vir->stopping || !vir->streaming) + goto end; + + if (!src_buf) + wait_for_completion(&cpy->cmpl); + + vir->frame_end = false; + spin_lock_irqsave(&vir->vbq_lock, lock_flags); + + if (!src_buf && !list_empty(&cpy->queue)) { + src_buf = list_first_entry(&cpy->queue, + struct rkisp_buffer, queue); + list_del(&src_buf->queue); + } + + if (src_buf && !vir->curr_buf && !list_empty(&vir->buf_queue)) { + vir->curr_buf = list_first_entry(&vir->buf_queue, + struct rkisp_buffer, queue); + list_del(&vir->curr_buf->queue); + } + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); + + if (!vir->curr_buf || !src_buf) + goto end; + + for (i = 0; i < vir->out_isp_fmt.mplanes; i++) { + u32 payload_size = vir->out_fmt.plane_fmt[i].sizeimage; + void *src = vb2_plane_vaddr(&src_buf->vb.vb2_buf, i); + void *dst = vb2_plane_vaddr(&vir->curr_buf->vb.vb2_buf, i); + + if (!src || !dst) + break; + vb2_set_plane_payload(&vir->curr_buf->vb.vb2_buf, i, payload_size); + memcpy(dst, src, payload_size); + } + + vir->curr_buf->vb.sequence = src_buf->vb.sequence; + vir->curr_buf->vb.vb2_buf.timestamp = src_buf->vb.vb2_buf.timestamp; + vb2_buffer_done(&vir->curr_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + vir->curr_buf = NULL; +end: + if (src_buf) + vb2_buffer_done(&src_buf->vb.vb2_buf, VB2_BUF_STATE_DONE); + src_buf = NULL; + spin_lock_irqsave(&vir->vbq_lock, lock_flags); + + if (!list_empty(&cpy->queue)) { + src_buf = list_first_entry(&cpy->queue, + struct rkisp_buffer, queue); + list_del(&src_buf->queue); + } else if (vir->stopping) { + vir->streaming = false; + } + + spin_unlock_irqrestore(&vir->vbq_lock, lock_flags); + } + + vir->frame_end = true; + + if (vir->stopping) { + vir->stopping = false; + vir->streaming = false; + wake_up(&vir->done); + } + + v4l2_dbg(1, rkisp_debug, &vir->ispdev->v4l2_dev, + "%s exit\n", __func__); +} + + /* * Most of registers inside rockchip isp1 have shadow register since * they must be not changed during processing a frame. @@ -1571,6 +1676,21 @@ static void rkisp_stop_streaming(struct vb2_queue *queue) if (!stream->streaming) goto end; + if (stream->id == RKISP_STREAM_VIR) { + stream->stopping = true; + wait_event_timeout(stream->done, + stream->frame_end, + msecs_to_jiffies(500)); + stream->streaming = false; + stream->stopping = false; + destroy_buf_queue(stream, VB2_BUF_STATE_ERROR); + + if (!completion_done(&dev->cap_dev.vir_cpy.cmpl)) + complete(&dev->cap_dev.vir_cpy.cmpl); + stream->conn_id = -1; + goto end; + } + rkisp_stream_stop(stream); if (stream->id == RKISP_STREAM_MP || stream->id == RKISP_STREAM_SP) { @@ -1652,6 +1772,28 @@ rkisp_start_streaming(struct vb2_queue *queue, unsigned int count) return -EBUSY; } + if (stream->id == RKISP_STREAM_VIR) { + struct rkisp_stream *t = &dev->cap_dev.stream[stream->conn_id]; + + if (t->streaming) { + INIT_WORK(&dev->cap_dev.vir_cpy.work, vir_cpy_image); + init_completion(&dev->cap_dev.vir_cpy.cmpl); + INIT_LIST_HEAD(&dev->cap_dev.vir_cpy.queue); + dev->cap_dev.vir_cpy.stream = stream; + schedule_work(&dev->cap_dev.vir_cpy.work); + ret = 0; + } else { + v4l2_err(&dev->v4l2_dev, + "no stream enable for iqtool\n"); + destroy_buf_queue(stream, VB2_BUF_STATE_QUEUED); + ret = -EINVAL; + } + + mutex_unlock(&dev->hw_dev->dev_lock); + + return ret; + } + memset(&stream->dbg, 0, sizeof(stream->dbg)); atomic_inc(&dev->cap_dev.refcnt); if (!dev->isp_inp || !stream->linked) { @@ -1787,7 +1929,7 @@ static int rkisp_stream_init(struct rkisp_device *dev, u32 id) switch (id) { case RKISP_STREAM_SP: - strlcpy(vdev->name, SP_VDEV_NAME, + strscpy(vdev->name, SP_VDEV_NAME, sizeof(vdev->name)); stream->ops = &rkisp_sp_streams_ops; stream->config = &rkisp_sp_stream_config; @@ -1795,25 +1937,32 @@ static int rkisp_stream_init(struct rkisp_device *dev, u32 id) stream->config->fmt_size = ARRAY_SIZE(sp_fmts); break; case RKISP_STREAM_DMATX0: - strlcpy(vdev->name, DMATX0_VDEV_NAME, + strscpy(vdev->name, DMATX0_VDEV_NAME, sizeof(vdev->name)); stream->ops = &rkisp2_dmatx0_streams_ops; stream->config = &rkisp2_dmatx0_stream_config; break; case RKISP_STREAM_DMATX2: - strlcpy(vdev->name, DMATX2_VDEV_NAME, + strscpy(vdev->name, DMATX2_VDEV_NAME, sizeof(vdev->name)); stream->ops = &rkisp2_dmatx2_streams_ops; stream->config = &rkisp2_dmatx1_stream_config; break; case RKISP_STREAM_DMATX3: - strlcpy(vdev->name, DMATX3_VDEV_NAME, + strscpy(vdev->name, DMATX3_VDEV_NAME, sizeof(vdev->name)); stream->ops = &rkisp2_dmatx3_streams_ops; stream->config = &rkisp2_dmatx3_stream_config; break; + case RKISP_STREAM_VIR: + strscpy(vdev->name, VIR_VDEV_NAME, + sizeof(vdev->name)); + stream->ops = NULL; + stream->config = &rkisp_mp_stream_config; + stream->conn_id = -1; + break; default: - strlcpy(vdev->name, MP_VDEV_NAME, + strscpy(vdev->name, MP_VDEV_NAME, sizeof(vdev->name)); stream->ops = &rkisp_mp_streams_ops; stream->config = &rkisp_mp_stream_config; @@ -1857,8 +2006,13 @@ int rkisp_register_stream_v21(struct rkisp_device *dev) ret = rkisp_stream_init(dev, RKISP_STREAM_DMATX3); if (ret < 0) goto err_free_tx2; + ret = rkisp_stream_init(dev, RKISP_STREAM_VIR); + if (ret < 0) + goto err_free_tx3; return 0; +err_free_tx3: + rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_DMATX3]); err_free_tx2: rkisp_unregister_stream_vdev(&cap_dev->stream[RKISP_STREAM_DMATX2]); err_free_tx0: @@ -1886,6 +2040,8 @@ void rkisp_unregister_stream_v21(struct rkisp_device *dev) rkisp_unregister_stream_vdev(stream); stream = &cap_dev->stream[RKISP_STREAM_DMATX3]; rkisp_unregister_stream_vdev(stream); + stream = &cap_dev->stream[RKISP_STREAM_VIR]; + rkisp_unregister_stream_vdev(stream); } /**************** Interrupter Handler ****************/ @@ -1905,7 +2061,7 @@ void rkisp_mi_v21_isr(u32 mis_val, struct rkisp_device *dev) for (i = 0; i < RKISP_MAX_STREAM; ++i) { stream = &dev->cap_dev.stream[i]; - if (!(mis_val & CIF_MI_FRAME(stream))) + if (!(mis_val & CIF_MI_FRAME(stream)) || stream->id == RKISP_STREAM_VIR) continue; if (i == RKISP_STREAM_DMATX0) diff --git a/drivers/media/platform/rockchip/isp/capture_v30.c b/drivers/media/platform/rockchip/isp/capture_v30.c index c757051d2ba9..ab1eea1e38c8 100644 --- a/drivers/media/platform/rockchip/isp/capture_v30.c +++ b/drivers/media/platform/rockchip/isp/capture_v30.c @@ -977,7 +977,10 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) (stream->frame_early && state == FRAME_IRQ)) goto end; } else { + spin_lock_irqsave(&stream->vbq_lock, lock_flags); buf = stream->curr_buf; + stream->curr_buf = NULL; + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); } if (buf) { diff --git a/drivers/media/platform/rockchip/isp/capture_v32.c b/drivers/media/platform/rockchip/isp/capture_v32.c index d8c43e902a02..82a0ba108a21 100644 --- a/drivers/media/platform/rockchip/isp/capture_v32.c +++ b/drivers/media/platform/rockchip/isp/capture_v32.c @@ -1408,7 +1408,10 @@ static int mi_frame_end(struct rkisp_stream *stream, u32 state) (stream->frame_early && state == FRAME_IRQ)) goto end; } else { + spin_lock_irqsave(&stream->vbq_lock, lock_flags); buf = stream->curr_buf; + stream->curr_buf = NULL; + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); } if (buf) { diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index bc140b3dd988..c3b9af95c581 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -3860,18 +3860,18 @@ void rkisp_chk_tb_over(struct rkisp_device *isp_dev) /* wait for all isp dev to register */ if (head->camera_num > 1) { - if (head->camera_num > hw->dev_num) { - v4l2_err(&isp_dev->v4l2_dev, - "thunderboot invalid camera num:%d, dev num:%d\n", - head->camera_num, hw->dev_num); - goto end; - } while (timeout--) { if (hw->dev_num >= head->camera_num && hw->isp[hw->dev_num - 1]->is_probe_end) break; usleep_range(200, 210); } + if (head->camera_num > hw->dev_num) { + v4l2_err(&isp_dev->v4l2_dev, + "thunderboot invalid camera num:%d, dev num:%d\n", + head->camera_num, hw->dev_num); + goto end; + } } for (i = 0; i < head->camera_num; i++) rkisp_save_tb_info(hw->isp[i]); diff --git a/drivers/rpmsg/rockchip_rpmsg_test.c b/drivers/rpmsg/rockchip_rpmsg_test.c index 08677d6975b0..08e882112e53 100644 --- a/drivers/rpmsg/rockchip_rpmsg_test.c +++ b/drivers/rpmsg/rockchip_rpmsg_test.c @@ -6,17 +6,22 @@ * Author: Hongming Zou */ +#include #include #include #include #include +#include #include #define LINUX_TEST_MSG_1 "Announce master ept id!" #define LINUX_TEST_MSG_2 "Rockchip rpmsg linux test pingpong!" -#define MSG_LIMIT 100 +#define MSG_LIMIT 10000 -struct instance_data { +/* different processor cores may need to adjust the value of this definition */ +#define LINUX_RPMSG_COMPENSATION (1) //ms + +struct rpmsg_info_t { int rx_count; }; @@ -25,18 +30,19 @@ static int rockchip_rpmsg_test_cb(struct rpmsg_device *rp, void *payload, { int ret; uint32_t remote_ept_id; - struct instance_data *idata = dev_get_drvdata(&rp->dev); + struct rpmsg_info_t *info = dev_get_drvdata(&rp->dev); remote_ept_id = src; dev_info(&rp->dev, "rx msg %s rx_count %d(remote_ept_id: 0x%x)\n", - (char *)payload, ++idata->rx_count, remote_ept_id); + (char *)payload, ++info->rx_count, remote_ept_id); /* test should not live forever */ - if (idata->rx_count >= MSG_LIMIT) { + if (info->rx_count >= MSG_LIMIT) { dev_info(&rp->dev, "Rockchip rpmsg test exit!\n"); return 0; } + mdelay(LINUX_RPMSG_COMPENSATION); /* send a new message now */ ret = rpmsg_sendto(rp->ept, LINUX_TEST_MSG_2, strlen(LINUX_TEST_MSG_2), remote_ept_id); if (ret) @@ -48,17 +54,17 @@ static int rockchip_rpmsg_test_probe(struct rpmsg_device *rp) { int ret; uint32_t master_ept_id, remote_ept_id; - struct instance_data *idata; + struct rpmsg_info_t *info; master_ept_id = rp->src; remote_ept_id = rp->dst; dev_info(&rp->dev, "new channel: 0x%x -> 0x%x!\n", master_ept_id, remote_ept_id); - idata = devm_kzalloc(&rp->dev, sizeof(*idata), GFP_KERNEL); - if (!idata) + info = devm_kzalloc(&rp->dev, sizeof(*info), GFP_KERNEL); + if (!info) return -ENOMEM; - dev_set_drvdata(&rp->dev, idata); + dev_set_drvdata(&rp->dev, info); /* * send a message to our remote processor, and tell remote @@ -69,7 +75,7 @@ static int rockchip_rpmsg_test_probe(struct rpmsg_device *rp) dev_err(&rp->dev, "rpmsg_send failed: %d\n", ret); return ret; } - + mdelay(LINUX_RPMSG_COMPENSATION); ret = rpmsg_sendto(rp->ept, LINUX_TEST_MSG_2, strlen(LINUX_TEST_MSG_2), remote_ept_id); if (ret) { dev_err(&rp->dev, "rpmsg_send failed: %d\n", ret); diff --git a/drivers/soc/rockchip/rockchip_amp.c b/drivers/soc/rockchip/rockchip_amp.c index 3bb0920eab42..db52d0956ee3 100644 --- a/drivers/soc/rockchip/rockchip_amp.c +++ b/drivers/soc/rockchip/rockchip_amp.c @@ -14,6 +14,7 @@ #include #include #include +#include #define RK_CPU_STATUS_OFF 0 #define RK_CPU_STATUS_ON 1 diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index ce6bfbc5a881..fc001d4d3a90 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -586,6 +586,7 @@ static void mpp_task_timeout_work(struct work_struct *work_s) mpp_dev_reset(mpp); mpp_power_off(mpp); + mpp_iommu_dev_deactivate(mpp->iommu_info, mpp); set_bit(TASK_STATE_TIMEOUT, &task->state); set_bit(TASK_STATE_DONE, &task->state); /* Wake up the GET thread */ diff --git a/drivers/video/rockchip/mpp/mpp_iommu.c b/drivers/video/rockchip/mpp/mpp_iommu.c index 88b87dc4c649..5bec7cf15956 100644 --- a/drivers/video/rockchip/mpp/mpp_iommu.c +++ b/drivers/video/rockchip/mpp/mpp_iommu.c @@ -453,6 +453,9 @@ static int mpp_iommu_handle(struct iommu_domain *iommu, return 0; } + if (mpp->cur_task) + mpp_task_dump_mem_region(mpp, mpp->cur_task); + if (mpp->dev_ops && mpp->dev_ops->dump_dev) mpp->dev_ops->dump_dev(mpp); else diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec.c b/drivers/video/rockchip/mpp/mpp_rkvdec.c index 7df16c615b4c..629ddcb218c1 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec.c @@ -1315,7 +1315,7 @@ static int rkvdec_3328_init(struct mpp_dev *mpp) goto done; } dec->aux_iova = -1; - mpp->iommu_info->hdl = rkvdec_3328_iommu_hdl; + mpp->fault_handler = rkvdec_3328_iommu_hdl; ret = rkvdec_devfreq_init(mpp); done: diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index eb112a5f157d..f45680d62f89 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -1541,7 +1541,7 @@ static int rkvdec2_core_probe(struct platform_device *pdev) mpp->dev_ops->task_worker = rkvdec2_hard_ccu_worker; irq_proc = rkvdec2_hard_ccu_irq; } - mpp->iommu_info->hdl = rkvdec2_ccu_iommu_fault_handle; + mpp->fault_handler = rkvdec2_ccu_iommu_fault_handle; kthread_init_work(&mpp->work, mpp->dev_ops->task_worker); /* get irq request */ diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 209d351cf8af..0d87eb476f40 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -2328,9 +2328,7 @@ static int rkvdec2_hard_ccu_enqueue(struct rkvdec2_ccu *ccu, writel(RKVDEC_CCU_BIT_CFG_DONE, ccu->reg_base + RKVDEC_CCU_CFG_DONE_BASE); mpp_task_run_end(mpp_task, timing_en); - /* pending to running */ set_bit(TASK_STATE_RUNNING, &mpp_task->state); - mpp_taskqueue_pending_to_run(queue, mpp_task); mpp_dbg_ccu("session %d task %d iova=%08x task->state=%lx link_mode=%08x\n", mpp_task->session->index, mpp_task->task_index, (u32)task->table->iova, mpp_task->state, @@ -2503,6 +2501,7 @@ void rkvdec2_hard_ccu_worker(struct kthread_work *work_s) rkvdec2_ccu_power_on(queue, dec->ccu); rkvdec2_hard_ccu_enqueue(dec->ccu, mpp_task, queue, mpp); + mpp_taskqueue_pending_to_run(queue, mpp_task); } /* 4. poweroff when running and pending list are empty */ diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index ee875ecf4082..5419954a8017 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -1190,7 +1190,7 @@ static int rkvenc_init(struct mpp_dev *mpp) } INIT_WORK(&enc->iommu_work, rkvenc_iommu_handle_work); - mpp->iommu_info->hdl = rkvenc_iommu_fault_handle; + mpp->fault_handler = rkvenc_iommu_fault_handle; return ret; } diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc2.c b/drivers/video/rockchip/mpp/mpp_rkvenc2.c index 993b19c485f1..c5783a454b73 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc2.c @@ -2445,8 +2445,7 @@ static int rkvenc_core_probe(struct platform_device *pdev) } mpp->session_max_buffers = RKVENC_SESSION_MAX_BUFFERS; enc->hw_info = to_rkvenc_info(mpp->var->hw_info); - if (mpp->iommu_info) - mpp->iommu_info->hdl = rkvenc2_iommu_fault_handle; + mpp->fault_handler = rkvenc2_iommu_fault_handle; rkvenc_procfs_init(mpp); rkvenc_procfs_ccu_init(mpp);