Merge commit 'c575feaee97f3c3f0d29ec8e5e4948e08f56cd61'

* commit 'c575feaee97f3c3f0d29ec8e5e4948e08f56cd61':
  Revert "usb: typec: typec_port_register_altmodes() depends on CONFIG_NO_GKI"
  media: i2c: os02k10: fix setting exposure error
  media: i2c: dw9800w: add ioctl set max logical pos
  video: rockchip: rga3: prevent calling mmget()/mmput() in spin_lock
  video: rockchip: rga3: refining time-consuming logs
  video: rockchip: rga3: destroy internal_buffer when user exits
  video: rockchip: rga3: signaled fecne after request commit failed
  UPSTREAM: mmc: dw_mmc: Fix potential null pointer risk
  drm/rockchip: rk628: vrefresh should not be zero
  phy/rockchip: inno-dsidphy: fref and _prediv should not be zero
  drm/rockchip: dsi2: sys_clk and pixel_clk should not be zero
  drm/rockchip: dsi: the bpp should not be zero
  media: rockchip: isp: fix build warning
  soc: rockchip: rk_dmabuf_procfs: check return value of platform_device_register_full()

Change-Id: I82396eff6f509f835cf56a36c87ed76394339549
This commit is contained in:
Tao Huang
2023-11-16 15:58:06 +08:00
19 changed files with 286 additions and 116 deletions

View File

@@ -660,7 +660,7 @@ dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
dsi->format = format;
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
if (bpp <= 0) {
DRM_DEV_ERROR(dsi->dev,
"failed to get bpp for pixel format %d\n",
dsi->format);

View File

@@ -628,6 +628,9 @@ static void dw_mipi_dsi2_phy_ratio_cfg(struct dw_mipi_dsi2 *dsi2)
pixel_clk = mode->crtc_clock * MSEC_PER_SEC;
ipi_clk = pixel_clk / 4;
if (!sys_clk || !ipi_clk)
return;
tmp = DIV_ROUND_CLOSEST_ULL(phy_hsclk << 16, ipi_clk);
regmap_write(dsi2->regmap, DSI2_PHY_IPI_RATIO_MAN_CFG,
PHY_IPI_RATIO(tmp));

View File

@@ -637,6 +637,9 @@ static int rk628_dsi_read_from_fifo(struct rk628_dsi *dsi,
u32 val;
int ret;
if (!vrefresh)
return -EINVAL;
ret = regmap_read_poll_timeout(dsi->regmap,
dsi->reg_base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_RD_CMD_BUSY),

View File

@@ -44,6 +44,7 @@ enum mode_e {
/* dw9800w device structure */
struct dw9800w_device {
struct v4l2_ctrl_handler ctrls_vcm;
struct v4l2_ctrl *focus;
struct i2c_client *client;
struct v4l2_subdev sd;
struct v4l2_device vdev;
@@ -52,13 +53,14 @@ struct dw9800w_device {
struct gpio_desc *power_gpio;
unsigned short current_related_pos;
unsigned short current_lens_pos;
unsigned int max_current;
unsigned int start_current;
unsigned int rated_current;
unsigned int step;
unsigned int step_mode;
unsigned int vcm_movefull_t;
unsigned int t_src;
unsigned int t_div;
unsigned int max_logicalpos;
struct __kernel_old_timeval start_move_tv;
struct __kernel_old_timeval end_move_tv;
@@ -67,7 +69,6 @@ struct dw9800w_device {
u32 module_index;
const char *module_facing;
struct rk_cam_vcm_cfg vcm_cfg;
int max_ma;
struct mutex lock;
};
@@ -217,22 +218,25 @@ static int dw9800w_get_pos(struct dw9800w_device *dev_vcm,
unsigned int *cur_pos)
{
struct i2c_client *client = dev_vcm->client;
unsigned int dac, position, range;
int ret;
unsigned int abs_step;
ret = dw9800w_read_reg(client, 0x03, 2, &abs_step);
range = dev_vcm->rated_current - dev_vcm->start_current;
ret = dw9800w_read_reg(client, 0x03, 2, &dac);
if (ret != 0)
goto err;
if (abs_step <= dev_vcm->start_current)
abs_step = VCMDRV_MAX_LOG;
else if ((abs_step > dev_vcm->start_current) &&
(abs_step <= dev_vcm->rated_current))
abs_step = (dev_vcm->rated_current - abs_step) / dev_vcm->step;
else
abs_step = 0;
if (dac <= dev_vcm->start_current) {
position = dev_vcm->max_logicalpos;
} else if ((dac > dev_vcm->start_current) &&
(dac <= dev_vcm->rated_current)) {
position = (dac - dev_vcm->start_current) * dev_vcm->max_logicalpos / range;
position = dev_vcm->max_logicalpos - position;
} else {
position = 0;
}
*cur_pos = abs_step;
*cur_pos = position;
dev_dbg(&client->dev, "%s: get position %d\n", __func__, *cur_pos);
return 0;
@@ -245,16 +249,18 @@ err:
static int dw9800w_set_pos(struct dw9800w_device *dev_vcm,
unsigned int dest_pos)
{
int ret;
unsigned int position = 0;
struct i2c_client *client = dev_vcm->client;
struct i2c_client *client = v4l2_get_subdevdata(&dev_vcm->sd);
unsigned int position;
unsigned int range;
u32 is_busy, i;
int ret;
if (dest_pos >= VCMDRV_MAX_LOG)
range = dev_vcm->rated_current - dev_vcm->start_current;
if (dest_pos >= dev_vcm->max_logicalpos)
position = dev_vcm->start_current;
else
position = dev_vcm->start_current +
(dev_vcm->step * (VCMDRV_MAX_LOG - dest_pos));
(range * (dev_vcm->max_logicalpos - dest_pos) / dev_vcm->max_logicalpos);
if (position > DW9800W_MAX_REG)
position = DW9800W_MAX_REG;
@@ -304,10 +310,10 @@ static int dw9800w_set_ctrl(struct v4l2_ctrl *ctrl)
if (ctrl->id == V4L2_CID_FOCUS_ABSOLUTE) {
if (dest_pos > VCMDRV_MAX_LOG) {
if (dest_pos > dev_vcm->max_logicalpos) {
dev_info(&client->dev,
"%s dest_pos is error. %d > %d\n",
__func__, dest_pos, VCMDRV_MAX_LOG);
__func__, dest_pos, dev_vcm->max_logicalpos);
return -EINVAL;
}
/* calculate move time */
@@ -318,7 +324,7 @@ static int dw9800w_set_ctrl(struct v4l2_ctrl *ctrl)
ret = dw9800w_set_pos(dev_vcm, dest_pos);
if (dev_vcm->step_mode == LSC_MODE)
dev_vcm->move_us = ((dev_vcm->vcm_movefull_t * (uint32_t)move_pos) /
VCMDRV_MAX_LOG);
dev_vcm->max_logicalpos);
else
dev_vcm->move_us = dev_vcm->vcm_movefull_t;
@@ -376,28 +382,27 @@ static const struct v4l2_subdev_internal_ops dw9800w_int_ops = {
static void dw9800w_update_vcm_cfg(struct dw9800w_device *dev_vcm)
{
struct i2c_client *client = dev_vcm->client;
int cur_dist;
if (dev_vcm->max_ma == 0) {
if (dev_vcm->max_current == 0) {
dev_err(&client->dev, "max current is zero");
return;
}
cur_dist = dev_vcm->vcm_cfg.rated_ma - dev_vcm->vcm_cfg.start_ma;
cur_dist = cur_dist * DW9800W_MAX_REG / dev_vcm->max_ma;
dev_vcm->step = (cur_dist + (VCMDRV_MAX_LOG - 1)) / VCMDRV_MAX_LOG;
if (dev_vcm->vcm_cfg.rated_ma > dev_vcm->max_current)
dev_vcm->max_current = DW9800W_MAX_REG;
dev_vcm->start_current = dev_vcm->vcm_cfg.start_ma *
DW9800W_MAX_REG / dev_vcm->max_ma;
DW9800W_MAX_REG / dev_vcm->max_current;
dev_vcm->rated_current = dev_vcm->vcm_cfg.rated_ma *
DW9800W_MAX_REG / dev_vcm->max_ma;
DW9800W_MAX_REG / dev_vcm->max_current;
dev_vcm->step_mode = dev_vcm->vcm_cfg.step_mode;
dev_info(&client->dev,
"vcm_cfg: %d, %d, %d, max_ma %d\n",
"vcm_cfg: %d, %d, %d, max_current %d\n",
dev_vcm->vcm_cfg.start_ma,
dev_vcm->vcm_cfg.rated_ma,
dev_vcm->vcm_cfg.step_mode,
dev_vcm->max_ma);
dev_vcm->max_current);
}
static long dw9800w_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
@@ -406,6 +411,7 @@ static long dw9800w_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
struct i2c_client *client = dev_vcm->client;
struct rk_cam_vcm_tim *vcm_tim;
struct rk_cam_vcm_cfg *vcm_cfg;
unsigned int max_logicalpos;
int ret = 0;
if (cmd == RK_VIDIOC_VCM_TIMEINFO) {
@@ -441,6 +447,16 @@ static long dw9800w_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
dev_vcm->vcm_cfg.rated_ma = vcm_cfg->rated_ma;
dev_vcm->vcm_cfg.step_mode = vcm_cfg->step_mode;
dw9800w_update_vcm_cfg(dev_vcm);
} else if (cmd == RK_VIDIOC_SET_VCM_MAX_LOGICALPOS) {
max_logicalpos = *(unsigned int *)arg;
if (max_logicalpos > 0) {
dev_vcm->max_logicalpos = max_logicalpos;
__v4l2_ctrl_modify_range(dev_vcm->focus,
0, dev_vcm->max_logicalpos, 1, dev_vcm->max_logicalpos);
}
dev_dbg(&client->dev,
"max_logicalpos %d\n", max_logicalpos);
} else {
dev_err(&client->dev,
"cmd 0x%x not supported\n", cmd);
@@ -460,6 +476,7 @@ static long dw9800w_compat_ioctl32(struct v4l2_subdev *sd,
struct rk_cam_compat_vcm_tim compat_vcm_tim;
struct rk_cam_vcm_tim vcm_tim;
struct rk_cam_vcm_cfg vcm_cfg;
unsigned int max_logicalpos;
long ret;
if (cmd == RK_VIDIOC_COMPAT_VCM_TIMEINFO) {
@@ -492,6 +509,12 @@ static long dw9800w_compat_ioctl32(struct v4l2_subdev *sd,
ret = dw9800w_ioctl(sd, cmd, &vcm_cfg);
else
ret = -EFAULT;
} else if (cmd == RK_VIDIOC_SET_VCM_MAX_LOGICALPOS) {
ret = copy_from_user(&max_logicalpos, up, sizeof(max_logicalpos));
if (!ret)
ret = dw9800w_ioctl(sd, cmd, &max_logicalpos);
else
ret = -EFAULT;
} else {
dev_err(&client->dev,
"cmd 0x%x not supported\n", cmd);
@@ -528,8 +551,9 @@ static int dw9800w_init_controls(struct dw9800w_device *dev_vcm)
v4l2_ctrl_handler_init(hdl, 1);
v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
0, VCMDRV_MAX_LOG, 1, 32);
dev_vcm->focus = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_FOCUS_ABSOLUTE,
0, dev_vcm->max_logicalpos, 1,
dev_vcm->max_logicalpos / 2);
if (hdl->error)
dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
@@ -585,7 +609,7 @@ static int dw9800w_probe(struct i2c_client *client,
{
struct device_node *np = of_node_get(client->dev.of_node);
struct dw9800w_device *dw9800w_dev;
unsigned int max_ma, start_ma, rated_ma, step_mode;
unsigned int max_current, start_ma, rated_ma, step_mode;
unsigned int t_src, t_div;
struct v4l2_subdev *sd;
char facing[2];
@@ -594,14 +618,14 @@ static int dw9800w_probe(struct i2c_client *client,
dev_info(&client->dev, "probing...\n");
if (of_property_read_u32(np,
OF_CAMERA_VCMDRV_MAX_CURRENT,
(unsigned int *)&max_ma)) {
max_ma = DW9800W_MAX_CURRENT;
(unsigned int *)&max_current)) {
max_current = DW9800W_MAX_CURRENT;
dev_info(&client->dev,
"could not get module %s from dts!\n",
OF_CAMERA_VCMDRV_MAX_CURRENT);
}
if (max_ma == 0)
max_ma = DW9800W_MAX_CURRENT;
if (max_current == 0)
max_current = DW9800W_MAX_CURRENT;
if (of_property_read_u32(np,
OF_CAMERA_VCMDRV_START_CURRENT,
@@ -680,6 +704,7 @@ static int dw9800w_probe(struct i2c_client *client,
dw9800w_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
dw9800w_dev->sd.internal_ops = &dw9800w_int_ops;
dw9800w_dev->max_logicalpos = VCMDRV_MAX_LOG;
ret = dw9800w_init_controls(dw9800w_dev);
if (ret)
goto err_cleanup;
@@ -704,13 +729,13 @@ static int dw9800w_probe(struct i2c_client *client,
if (ret)
dev_err(&client->dev, "v4l2 async register subdev failed\n");
dw9800w_dev->max_ma = max_ma;
dw9800w_dev->max_current = max_current;
dw9800w_dev->vcm_cfg.start_ma = start_ma;
dw9800w_dev->vcm_cfg.rated_ma = rated_ma;
dw9800w_dev->vcm_cfg.step_mode = step_mode;
dw9800w_update_vcm_cfg(dw9800w_dev);
dw9800w_dev->move_us = 0;
dw9800w_dev->current_related_pos = VCMDRV_MAX_LOG;
dw9800w_dev->current_related_pos = dw9800w_dev->max_logicalpos;
dw9800w_dev->start_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());
dw9800w_dev->end_move_tv = ns_to_kernel_old_timeval(ktime_get_ns());

View File

@@ -1806,6 +1806,7 @@ static int os02k10_set_ctrl(struct v4l2_ctrl *ctrl)
s64 max;
int ret = 0;
u32 val = 0;
u32 reg_data;
/* Propagate change of current control to all related controls */
switch (ctrl->id) {
@@ -1835,23 +1836,53 @@ static int os02k10_set_ctrl(struct v4l2_ctrl *ctrl)
}
break;
case V4L2_CID_ANALOGUE_GAIN:
/*
* dgain reg format is 4.10bits, again reg format is 4.4bits
* 1x is 64, 6 decimal places
*/
if (ctrl->val > 992) {
dgain = ctrl->val * 1024 / 992;
dgain = ctrl->val * 1024 / 992; //15.5X * 64 = 992
again = 992;
} else {
dgain = 1024;
dgain = 1024; //move 10 bits left
again = ctrl->val;
}
dev_dbg(&client->dev, "gain %d, ag 0x%x, dg 0x%x\n",
ctrl->val, again, dgain);
ret = os02k10_write_reg(os02k10->client,
ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_REL_GAIN_REG_H,
OS02K10_REG_VALUE_08BIT, &reg_data);
reg_data = reg_data & 0xf0;
ret |= os02k10_write_reg(os02k10->client,
OS02K10_AEC_LONG_REL_GAIN_REG_H,
OS02K10_REG_VALUE_16BIT,
(again << 2) & 0xff0);
OS02K10_REG_VALUE_08BIT,
((again >> 6) & 0x0f) | reg_data);
ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_REL_GAIN_REG_L,
OS02K10_REG_VALUE_08BIT, &reg_data);
reg_data = reg_data & 0x0f;
ret |= os02k10_write_reg(os02k10->client,
OS02K10_AEC_LONG_REL_GAIN_REG_L,
OS02K10_REG_VALUE_08BIT,
(((again >> 2) & 0x0f) << 4) | reg_data);
ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_DIG_GAIN_REG_H,
OS02K10_REG_VALUE_08BIT, &reg_data);
reg_data = reg_data & 0xf0;
ret |= os02k10_write_reg(os02k10->client,
OS02K10_AEC_LONG_DIG_GAIN_REG_H,
OS02K10_REG_VALUE_24BIT,
(dgain << 6) & 0xfffc0);
OS02K10_REG_VALUE_08BIT,
((dgain >> 10) & 0x0f) | reg_data);
ret |= os02k10_write_reg(os02k10->client,
OS02K10_AEC_LONG_DIG_GAIN_REG_M,
OS02K10_REG_VALUE_08BIT,
(dgain >> 2) & 0xff);
ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_DIG_GAIN_REG_L,
OS02K10_REG_VALUE_08BIT, &reg_data);
reg_data = reg_data & 0x3f;
ret |= os02k10_write_reg(os02k10->client,
OS02K10_AEC_LONG_DIG_GAIN_REG_L,
OS02K10_REG_VALUE_08BIT,
((dgain & 0x03) << 6) | reg_data);
break;
case V4L2_CID_VBLANK:
dev_dbg(&client->dev, "set blank value 0x%x\n", ctrl->val);

View File

@@ -1150,7 +1150,8 @@ static void rdbk_frame_end(struct rkisp_stream *stream)
if (!ret) {
denominator = sensor->fi.interval.denominator;
numerator = sensor->fi.interval.numerator;
time = numerator * 1000 / denominator * 1000 * 1000;
if (denominator)
time = numerator * 1000 / denominator * 1000 * 1000;
if (numerator)
fps = denominator / numerator;
}

View File

@@ -330,6 +330,11 @@ int rkisp_attach_hw(struct rkisp_device *isp)
return -EINVAL;
}
if (hw->dev_num >= DEV_MAX) {
dev_err(isp->dev, "failed attach isp hw, max dev:%d\n", DEV_MAX);
return -EINVAL;
}
isp->dev_id = hw->dev_num;
hw->isp[hw->dev_num] = isp;
hw->dev_num++;

View File

@@ -82,6 +82,8 @@ static int rkisp_csi_link_setup(struct media_entity *entity,
id = local->index - 1;
if (id && id < RKISP_STREAM_DMATX3)
stream = &csi->ispdev->cap_dev.stream[id + 1];
if (id >= ARRAY_SIZE(csi->sink))
return -EINVAL;
if (flags & MEDIA_LNK_FL_ENABLED) {
if (csi->sink[id].linked) {
ret = -EBUSY;

View File

@@ -210,36 +210,23 @@ static void rkisp_params_vb2_stop_streaming(struct vb2_queue *vq)
struct rkisp_device *dev = params_vdev->dev;
struct rkisp_buffer *buf;
unsigned long flags;
int i;
/* stop params input firstly */
spin_lock_irqsave(&params_vdev->config_lock, flags);
params_vdev->streamon = false;
wake_up(&dev->sync_onoff);
spin_unlock_irqrestore(&params_vdev->config_lock, flags);
for (i = 0; i < RKISP_ISP_PARAMS_REQ_BUFS_MAX; i++) {
spin_lock_irqsave(&params_vdev->config_lock, flags);
if (!list_empty(&params_vdev->params)) {
buf = list_first_entry(&params_vdev->params,
struct rkisp_buffer, queue);
list_del(&buf->queue);
spin_unlock_irqrestore(&params_vdev->config_lock,
flags);
} else {
spin_unlock_irqrestore(&params_vdev->config_lock,
flags);
break;
}
while (!list_empty(&params_vdev->params)) {
buf = list_first_entry(&params_vdev->params,
struct rkisp_buffer, queue);
list_del(&buf->queue);
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
}
if (params_vdev->cur_buf) {
buf = params_vdev->cur_buf;
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
params_vdev->cur_buf = NULL;
}
spin_unlock_irqrestore(&params_vdev->config_lock, flags);
rkisp_params_disable_isp(params_vdev);
/* clean module params */

View File

@@ -4337,7 +4337,7 @@ int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev)
ret = rkisp_alloc_buffer(params_vdev->dev, &priv_val->buf_3dlut[i]);
if (ret) {
dev_err(dev, "can not alloc buffer\n");
goto err;
goto err_3dlut;
}
}
@@ -4348,7 +4348,7 @@ int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev)
ret = rkisp_alloc_buffer(params_vdev->dev, &priv_val->buf_lsclut[i]);
if (ret) {
dev_err(dev, "can not alloc buffer\n");
goto err;
goto err_lsclut;
}
}
@@ -4357,15 +4357,16 @@ int rkisp_init_params_vdev_v21(struct rkisp_isp_params_vdev *params_vdev)
params_vdev->priv_ops = &rkisp_v21_isp_params_ops;
rkisp_clear_first_param_v2x(params_vdev);
return 0;
err:
for (i = 0; i < RKISP_PARAM_3DLUT_BUF_NUM; i++)
err_lsclut:
for (i -= 1; i >= 0; i--)
rkisp_free_buffer(params_vdev->dev, &priv_val->buf_lsclut[i]);
i = RKISP_PARAM_3DLUT_BUF_NUM;
err_3dlut:
for (i -= 1; i >= 0; i--)
rkisp_free_buffer(params_vdev->dev, &priv_val->buf_3dlut[i]);
for (i = 0; i < RKISP_PARAM_LSC_LUT_BUF_NUM; i++)
rkisp_free_buffer(params_vdev->dev, &priv_val->buf_lsclut[i]);
vfree(params_vdev->isp21_params);
kfree(priv_val);
return ret;
}

View File

@@ -344,6 +344,9 @@ static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno,
* PLL_Output_Frequency: it is equal to DDR-Clock-Frequency * 2
*/
fref = prate / 2;
if (!fref)
return 0;
if (rate > 1000000000UL)
fout = 1000000000UL;
else
@@ -357,6 +360,9 @@ static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno,
u64 tmp;
u32 delta;
if (!_prediv)
continue;
tmp = (u64)fout * _prediv;
do_div(tmp, fref);
_fbdiv = tmp;

View File

@@ -186,8 +186,10 @@ static int __init rk_dmabuf_init(void)
struct proc_dir_entry *root = proc_mkdir("rk_dmabuf", NULL);
pdev = platform_device_register_full(&dev_info);
dma_set_max_seg_size(&pdev->dev, (unsigned int)DMA_BIT_MASK(64));
dmabuf_dev = pdev ? &pdev->dev : NULL;
if (!IS_ERR(pdev)) {
dmabuf_dev = &pdev->dev;
dma_set_max_seg_size(dmabuf_dev, (unsigned int)DMA_BIT_MASK(64));
}
proc_create_single("sgt", 0, root, rk_dmabuf_sgt_show);
proc_create_single("dev", 0, root, rk_dmabuf_dev_show);

View File

@@ -86,6 +86,12 @@ enum rga_scale_down_mode {
RGA_SCALE_DOWN_AVG = 0x1,
};
enum RGA_SCHEDULER_CORE {
RGA_SCHEDULER_RGA3_CORE0 = 1 << 0,
RGA_SCHEDULER_RGA3_CORE1 = 1 << 1,
RGA_SCHEDULER_RGA2_CORE0 = 1 << 2,
};
/* RGA process mode enum */
enum {
BITBLT_MODE = 0x0,

View File

@@ -37,6 +37,7 @@ const char *rga_get_rotate_mode_str(uint8_t mode);
const char *rga_get_blend_mode_str(enum rga_alpha_blend_mode mode);
const char *rga_get_memory_type_str(uint8_t type);
const char *rga_get_mmu_type_str(enum rga_mmu mmu_type);
const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core);
void rga_convert_addr(struct rga_img_info_t *img, bool before_vir_get_channel);
void rga_swap_pd_mode(struct rga_req *req_rga);

View File

@@ -2323,6 +2323,7 @@ static int rga2_init_reg(struct rga_job *job)
struct rga2_req req;
int ret = 0;
struct rga_scheduler_t *scheduler = NULL;
ktime_t timestamp = ktime_get();
scheduler = job->scheduler;
if (unlikely(scheduler == NULL)) {
@@ -2396,6 +2397,10 @@ static int rga2_init_reg(struct rga_job *job)
return -EINVAL;
}
if (DEBUGGER_EN(TIME))
pr_info("request[%d], generate register cost time %lld us\n",
job->request_id, ktime_us_delta(ktime_get(), timestamp));
return ret;
}
@@ -2599,8 +2604,8 @@ static int rga2_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
rga_read(RGA2_INT, scheduler));
if (DEBUGGER_EN(TIME))
pr_info("set cmd use time = %lld\n",
ktime_us_delta(now, job->timestamp));
pr_info("request[%d], set register cost time %lld us\n",
job->request_id, ktime_us_delta(now, job->timestamp));
job->hw_running_time = now;
job->hw_recoder_time = now;

View File

@@ -1955,6 +1955,7 @@ static int rga3_init_reg(struct rga_job *job)
struct rga3_req req;
int ret = 0;
struct rga_scheduler_t *scheduler = NULL;
ktime_t timestamp = ktime_get();
scheduler = job->scheduler;
if (unlikely(scheduler == NULL)) {
@@ -1984,6 +1985,10 @@ static int rga3_init_reg(struct rga_job *job)
return -EINVAL;
}
if (DEBUGGER_EN(TIME))
pr_info("request[%d], generate register cost time %lld us\n",
job->request_id, ktime_us_delta(ktime_get(), timestamp));
return ret;
}
@@ -2070,7 +2075,8 @@ static int rga3_set_reg(struct rga_job *job, struct rga_scheduler_t *scheduler)
}
if (DEBUGGER_EN(TIME))
pr_info("set cmd use time = %lld\n", ktime_us_delta(now, job->timestamp));
pr_info("request[%d], set register cost time %lld us\n",
job->request_id, ktime_us_delta(now, job->timestamp));
job->hw_running_time = now;
job->hw_recoder_time = now;

View File

@@ -604,6 +604,20 @@ const char *rga_get_mmu_type_str(enum rga_mmu mmu_type)
}
}
const char *rga_get_core_name(enum RGA_SCHEDULER_CORE core)
{
switch (core) {
case RGA_SCHEDULER_RGA3_CORE0:
return "RGA3_core0";
case RGA_SCHEDULER_RGA3_CORE1:
return "RGA3_core1";
case RGA_SCHEDULER_RGA2_CORE0:
return "RGA2_core0";
default:
return "unknown_core";
}
}
void rga_convert_addr(struct rga_img_info_t *img, bool before_vir_get_channel)
{
/*

View File

@@ -13,6 +13,7 @@
#include "rga_mm.h"
#include "rga_iommu.h"
#include "rga_debugger.h"
#include "rga_common.h"
static void rga_job_free(struct rga_job *job)
{
@@ -40,12 +41,13 @@ static void rga_job_get(struct rga_job *job)
static int rga_job_cleanup(struct rga_job *job)
{
if (DEBUGGER_EN(TIME))
pr_err("(pid:%d) job clean use time = %lld\n", job->pid,
ktime_us_delta(ktime_get(), job->timestamp));
rga_job_put(job);
if (DEBUGGER_EN(TIME))
pr_info("request[%d], job cleanup total cost time %lld us\n",
job->request_id,
ktime_us_delta(ktime_get(), job->timestamp));
return 0;
}
@@ -272,11 +274,11 @@ struct rga_job *rga_job_done(struct rga_scheduler_t *scheduler)
if (DEBUGGER_EN(DUMP_IMAGE))
rga_dump_job_image(job);
if (DEBUGGER_EN(TIME)) {
pr_info("hw use time = %lld\n", ktime_us_delta(now, job->hw_running_time));
pr_info("(pid:%d) job done use time = %lld\n", job->pid,
ktime_us_delta(now, job->timestamp));
}
if (DEBUGGER_EN(TIME))
pr_info("request[%d], hardware[%s] cost time %lld us\n",
job->request_id,
rga_get_core_name(scheduler->core),
ktime_us_delta(now, job->hw_running_time));
rga_mm_unmap_job_info(job);
@@ -492,7 +494,7 @@ static bool rga_is_need_current_mm(struct rga_req *req)
return false;
}
static int rga_request_get_current_mm(struct rga_request *request)
static struct mm_struct *rga_request_get_current_mm(struct rga_request *request)
{
int i;
@@ -500,23 +502,21 @@ static int rga_request_get_current_mm(struct rga_request *request)
if (rga_is_need_current_mm(&(request->task_list[i]))) {
mmgrab(current->mm);
mmget(current->mm);
request->current_mm = current->mm;
break;
return current->mm;
}
}
return 0;
return NULL;
}
static void rga_request_put_current_mm(struct rga_request *request)
static void rga_request_put_current_mm(struct mm_struct *mm)
{
if (request->current_mm == NULL)
if (mm == NULL)
return;
mmput(request->current_mm);
mmdrop(request->current_mm);
request->current_mm = NULL;
mmput(mm);
mmdrop(mm);
}
static int rga_request_add_acquire_fence_callback(int acquire_fence_fd,
@@ -693,6 +693,7 @@ static int rga_request_scheduler_job_abort(struct rga_request *request)
static void rga_request_release_abort(struct rga_request *request, int err_code)
{
unsigned long flags;
struct mm_struct *current_mm;
struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager;
if (rga_request_scheduler_job_abort(request) > 0)
@@ -707,11 +708,13 @@ static void rga_request_release_abort(struct rga_request *request, int err_code)
request->is_running = false;
request->is_done = false;
rga_request_put_current_mm(request);
current_mm = request->current_mm;
request->current_mm = NULL;
spin_unlock_irqrestore(&request->lock, flags);
rga_request_put_current_mm(current_mm);
rga_dma_fence_signal(request->release_fence, err_code);
mutex_lock(&request_manager->lock);
@@ -848,12 +851,34 @@ int rga_request_commit(struct rga_request *request)
static void rga_request_acquire_fence_signaled_cb(struct dma_fence *fence,
struct dma_fence_cb *_waiter)
{
int ret;
unsigned long flags;
struct mm_struct *current_mm;
struct rga_fence_waiter *waiter = (struct rga_fence_waiter *)_waiter;
struct rga_request *request = (struct rga_request *)waiter->private;
struct rga_pending_request_manager *request_manager = rga_drvdata->pend_request_manager;
if (rga_request_commit(request))
pr_err("rga request[%d] commit failed!\n", request->id);
ret = rga_request_commit(request);
if (ret < 0) {
pr_err("acquire_fence callback: rga request[%d] commit failed!\n", request->id);
spin_lock_irqsave(&request->lock, flags);
request->is_running = false;
current_mm = request->current_mm;
request->current_mm = NULL;
spin_unlock_irqrestore(&request->lock, flags);
rga_request_put_current_mm(current_mm);
/*
* Since the callback is called while holding &dma_fence.lock,
* the _locked API is used here.
*/
if (dma_fence_get_status_locked(request->release_fence) == 0)
dma_fence_signal_locked(request->release_fence);
}
mutex_lock(&request_manager->lock);
rga_request_put(request);
@@ -866,6 +891,7 @@ int rga_request_release_signal(struct rga_scheduler_t *scheduler, struct rga_job
{
struct rga_pending_request_manager *request_manager;
struct rga_request *request;
struct mm_struct *current_mm;
int finished_count, failed_count;
bool is_finished = false;
unsigned long flags;
@@ -902,18 +928,18 @@ int rga_request_release_signal(struct rga_scheduler_t *scheduler, struct rga_job
spin_unlock_irqrestore(&request->lock, flags);
rga_job_cleanup(job);
if ((failed_count + finished_count) >= request->task_count) {
spin_lock_irqsave(&request->lock, flags);
request->is_running = false;
request->is_done = true;
rga_request_put_current_mm(request);
current_mm = request->current_mm;
request->current_mm = NULL;
spin_unlock_irqrestore(&request->lock, flags);
rga_request_put_current_mm(current_mm);
rga_dma_fence_signal(request->release_fence, request->ret);
is_finished = true;
@@ -937,6 +963,13 @@ int rga_request_release_signal(struct rga_scheduler_t *scheduler, struct rga_job
mutex_unlock(&request_manager->lock);
if (DEBUGGER_EN(TIME))
pr_info("request[%d], job done total cost time %lld us\n",
job->request_id,
ktime_us_delta(ktime_get(), job->timestamp));
rga_job_cleanup(job);
return 0;
}
@@ -1066,6 +1099,9 @@ int rga_request_submit(struct rga_request *request)
int ret = 0;
unsigned long flags;
struct dma_fence *release_fence;
struct mm_struct *current_mm;
current_mm = rga_request_get_current_mm(request);
spin_lock_irqsave(&request->lock, flags);
@@ -1073,14 +1109,16 @@ int rga_request_submit(struct rga_request *request)
spin_unlock_irqrestore(&request->lock, flags);
pr_err("can not re-config when request is running\n");
return -EFAULT;
ret = -EFAULT;
goto err_put_current_mm;
}
if (request->task_list == NULL) {
spin_unlock_irqrestore(&request->lock, flags);
pr_err("can not find task list from id[%d]\n", request->id);
return -EINVAL;
ret = -EINVAL;
goto err_put_current_mm;
}
/* Reset */
@@ -1088,8 +1126,7 @@ int rga_request_submit(struct rga_request *request)
request->is_done = false;
request->finished_task_count = 0;
request->failed_task_count = 0;
rga_request_get_current_mm(request);
request->current_mm = current_mm;
/* Unlock after ensuring that the current request will not be resubmitted. */
spin_unlock_irqrestore(&request->lock, flags);
@@ -1099,7 +1136,7 @@ int rga_request_submit(struct rga_request *request)
if (IS_ERR(release_fence)) {
pr_err("Can not alloc release fence!\n");
ret = IS_ERR(release_fence);
goto error_put_current_mm;
goto err_reset_request;
}
request->release_fence = release_fence;
@@ -1148,14 +1185,17 @@ err_put_release_fence:
request->release_fence = NULL;
}
error_put_current_mm:
err_reset_request:
spin_lock_irqsave(&request->lock, flags);
rga_request_put_current_mm(request);
request->current_mm = NULL;
request->is_running = false;
spin_unlock_irqrestore(&request->lock, flags);
err_put_current_mm:
rga_request_put_current_mm(current_mm);
return ret;
}
@@ -1244,6 +1284,7 @@ int rga_request_free(struct rga_request *request)
static void rga_request_kref_release(struct kref *ref)
{
struct rga_request *request;
struct mm_struct *current_mm;
unsigned long flags;
request = container_of(ref, struct rga_request, refcount);
@@ -1253,16 +1294,22 @@ static void rga_request_kref_release(struct kref *ref)
spin_lock_irqsave(&request->lock, flags);
rga_request_put_current_mm(request);
rga_dma_fence_put(request->release_fence);
current_mm = request->current_mm;
request->current_mm = NULL;
if (!request->is_running || request->is_done) {
spin_unlock_irqrestore(&request->lock, flags);
rga_request_put_current_mm(current_mm);
goto free_request;
}
spin_unlock_irqrestore(&request->lock, flags);
rga_request_put_current_mm(current_mm);
rga_request_scheduler_job_abort(request);
free_request:

View File

@@ -840,6 +840,11 @@ static int rga_mm_handle_remove(int id, void *ptr, void *data)
return 0;
}
static void rga_mm_buffer_destroy(struct rga_internal_buffer *buffer)
{
rga_mm_kref_release_buffer(&buffer->refcount);
}
static struct rga_internal_buffer *
rga_mm_lookup_external(struct rga_mm *mm_session,
struct rga_external_buffer *external_buffer,
@@ -1991,6 +1996,7 @@ error_unmap_buffer:
int rga_mm_map_job_info(struct rga_job *job)
{
int ret;
ktime_t timestamp = ktime_get();
if (job->flags & RGA_JOB_USE_HANDLE) {
ret = rga_mm_get_handle_info(job);
@@ -1998,12 +2004,20 @@ int rga_mm_map_job_info(struct rga_job *job)
pr_err("failed to get buffer from handle\n");
return ret;
}
if (DEBUGGER_EN(TIME))
pr_info("request[%d], get buffer_handle info cost %lld us\n",
job->request_id, ktime_us_delta(ktime_get(), timestamp));
} else {
ret = rga_mm_map_buffer_info(job);
if (ret < 0) {
pr_err("failed to map buffer\n");
return ret;
}
if (DEBUGGER_EN(TIME))
pr_info("request[%d], map buffer cost %lld us\n",
job->request_id, ktime_us_delta(ktime_get(), timestamp));
}
return 0;
@@ -2011,10 +2025,21 @@ int rga_mm_map_job_info(struct rga_job *job)
void rga_mm_unmap_job_info(struct rga_job *job)
{
if (job->flags & RGA_JOB_USE_HANDLE)
ktime_t timestamp = ktime_get();
if (job->flags & RGA_JOB_USE_HANDLE) {
rga_mm_put_handle_info(job);
else
if (DEBUGGER_EN(TIME))
pr_info("request[%d], put buffer_handle info cost %lld us\n",
job->request_id, ktime_us_delta(ktime_get(), timestamp));
} else {
rga_mm_unmap_buffer_info(job);
if (DEBUGGER_EN(TIME))
pr_info("request[%d], unmap buffer cost %lld us\n",
job->request_id, ktime_us_delta(ktime_get(), timestamp));
}
}
uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer,
@@ -2142,9 +2167,9 @@ int rga_mm_session_release_buffer(struct rga_session *session)
idr_for_each_entry(&mm->memory_idr, buffer, i) {
if (session == buffer->session) {
pr_err("[tgid:%d] Decrement the reference of handle[%d] when the user exits\n",
pr_err("[tgid:%d] Destroy handle[%d] when the user exits\n",
session->tgid, buffer->handle);
kref_put(&buffer->refcount, rga_mm_kref_release_buffer);
rga_mm_buffer_destroy(buffer);
}
}