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