mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
Merge commit '0c4fa77794ce128089a9f9523d4615d4f2835ec5'
* commit '0c4fa77794ce128089a9f9523d4615d4f2835ec5': rpmsg: rockchip_test: add delay compensation media: rockchip: isp: add iqtool video for isp21 arm64: dts: rockchip: rk3399pro-npu: dis u1 and u2 state for dwc3 arm64: dts: rockchip: rk1808: dis u1 and u2 state for dwc3 arm64: dts: rockchip: dis u1 and u2 state for rk3528 dwc3 ARM: dts: rockchip: update rk808 for rk3288-evb-rk808-linux.dts ARM: dts: rockchip: Add mmc aliases for rk3288-linux.dtsi drm/bridge: synopsys: dw-hdmi-qp: Fix frl switch error when switching resolution and color at the same time ARM: configs: enable HDMI and MULTICODECS for rockchip_linux_defconfig UPSTREAM: ASoC: rt5640: Remove the sysclk and sysclk_src checking video: rockchip: mpp: fix some iommu hdl register issue media: rockchip: isp: fix get tb info soc: rockchip: rockchip_system_monitor: Don't init wide temp when tz is NULL video: rockchip: mpp: fix task re-add running_list issue arm64: dts: rockchip: rk3588-evb3-lp5: update for v11 board media: rockchip: isp: fix list buf delete err soc: rockchip: amp: include rockchip_amp.h for function prototypes arm64: dts: rockchip: rk3562-rk817-tablet: adjust vcm configs to reduce noise media: i2c: dw9763: optimize open/close procedure to reduce noise UPSTREAM: dt-bindings: usb: snps,dwc3: Add 'snps,parkmode-disable-hs-quirk' quirk Change-Id: Iaab1b5d91a4a16c24fb30938d520087b77861a73
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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";
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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 = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
|
||||
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";
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
#include <media/v4l2-device.h>
|
||||
#include <linux/rk_vcm_head.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -6,17 +6,22 @@
|
||||
* Author: Hongming Zou <hongming.zou@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/rpmsg/rockchip_rpmsg.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/virtio.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/rockchip/rockchip_sip.h>
|
||||
#include <soc/rockchip/rockchip_amp.h>
|
||||
|
||||
#define RK_CPU_STATUS_OFF 0
|
||||
#define RK_CPU_STATUS_ON 1
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user