Merge commit '438259ec8c6f9b3659cc27d54f01e2a224b1c615'

* commit '438259ec8c6f9b3659cc27d54f01e2a224b1c615':
  media: rockchip: vicap fixes error use_count for switch device mode
  media: rockchip: vicap fixes error start stream of aov for rv1126b
  arm64: dts: rockchip: rk3562: remove unnecessary references to rkcif_mmu
  arm64: dts: rockchip: rv1126b-evb-cam-csi0: add imx586 support
  ARM: configs: rv1126b-evb: enable imx586
  arm64: dts: rockchip: rk3588-evb7-v11: support usbhost3.0
  iio: imu: inv_icm42670: fix dead lock when resume
  video: rockchip: mpp: rkvenc2: add governor and device for devfreq
  thermal: rockchip: Remove npu thermal for rv1126b
  arm64: dts: rockchip: rv1126b: Remove npu thermal
  video: rockchip: mpp_osal: Add func to get dma iommu mapping
  arm64: dts: rockchip: rv1126b: add opp-510M/600M for npu
  clk: rockchip: clk-pvtpll: add 510M/600M frequency point for rv1126b npu
  arm64: dts: rockchip: rk3528: Remove pcie2x1 SRST_PRESETN_CRU_PCIE reset
  arm64: dts: rockchip: rv1126b-evb1-v10: Adapt the PMU IO states for the sleep mode
  arm64: dts: rockchip: rv1126b-evb3-v10: Add rtc/rockchip_suspend support
  arm64: dts: rockchip: rv1126b: Add label to reserved-memory node
  arm64: dts: rockchip: rv1126b-evb2-v10: Resolve the leakage issue in sleep mode
  media: i2c: sc850sl: add support hw standby

Change-Id: I56bc3ae8f65e08842488163fbe4ab6791b2f5a5a
This commit is contained in:
Tao Huang
2025-05-30 19:40:30 +08:00
18 changed files with 522 additions and 181 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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";
};

View File

@@ -937,11 +937,11 @@
};
&usbhost3_0 {
status = "disabled";
status = "okay";
};
&usbhost_dwc3_0 {
status = "disabled";
status = "okay";
};
&work_led {

View File

@@ -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";

View File

@@ -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)
)
>;
};

View File

@@ -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>;
};
};

View File

@@ -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

View File

@@ -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 {

View File

@@ -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>;

View File

@@ -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[] = {

View File

@@ -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;
}

View File

@@ -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");

View File

@@ -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;

View File

@@ -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,

View File

@@ -33,6 +33,10 @@
#include <soc/rockchip/rockchip_system_monitor.h>
#include <soc/rockchip/rockchip_iommu.h>
#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;

View File

@@ -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);

View File

@@ -10,10 +10,13 @@
#include <linux/platform_device.h>
#include <linux/pm_wakeup.h>
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