| .. | .. |
|---|
| 33 | 33 | */ |
|---|
| 34 | 34 | |
|---|
| 35 | 35 | #include <linux/clk.h> |
|---|
| 36 | +#include <linux/compat.h> |
|---|
| 36 | 37 | #include <linux/iopoll.h> |
|---|
| 37 | 38 | #include <linux/pm_runtime.h> |
|---|
| 38 | 39 | #include <linux/regmap.h> |
|---|
| .. | .. |
|---|
| 42 | 43 | #include <linux/kfifo.h> |
|---|
| 43 | 44 | #include <linux/interrupt.h> |
|---|
| 44 | 45 | #include <linux/rk-preisp.h> |
|---|
| 45 | | -#include <linux/rkisp21-config.h> |
|---|
| 46 | +#include <linux/rk-isp21-config.h> |
|---|
| 46 | 47 | #include <linux/iommu.h> |
|---|
| 47 | 48 | #include <media/v4l2-event.h> |
|---|
| 48 | 49 | #include <media/media-entity.h> |
|---|
| 49 | 50 | |
|---|
| 50 | 51 | #include "common.h" |
|---|
| 52 | +#include "isp_external.h" |
|---|
| 51 | 53 | #include "regs.h" |
|---|
| 52 | 54 | #include "rkisp_tb_helper.h" |
|---|
| 53 | 55 | |
|---|
| .. | .. |
|---|
| 82 | 84 | * | +---------------------------------------------------+ | |
|---|
| 83 | 85 | * +---------------------------------------------------------+ |
|---|
| 84 | 86 | */ |
|---|
| 87 | + |
|---|
| 88 | +static void rkisp_config_cmsk(struct rkisp_device *dev); |
|---|
| 85 | 89 | |
|---|
| 86 | 90 | struct backup_reg { |
|---|
| 87 | 91 | const u32 base; |
|---|
| .. | .. |
|---|
| 188 | 192 | u32 code = dev->isp_sdev.in_frm.code; |
|---|
| 189 | 193 | u32 src_w = dev->isp_sdev.in_frm.width; |
|---|
| 190 | 194 | u32 src_h = dev->isp_sdev.in_frm.height; |
|---|
| 191 | | - u32 dest_w, dest_h, w, h; |
|---|
| 195 | + u32 dest_w, dest_h, w, h, max_size, max_h, max_w; |
|---|
| 192 | 196 | int ret = 0; |
|---|
| 193 | 197 | |
|---|
| 194 | 198 | if (!crop) |
|---|
| 195 | 199 | return -EINVAL; |
|---|
| 196 | 200 | |
|---|
| 197 | | - if (dev->isp_ver == ISP_V12) { |
|---|
| 198 | | - w = clamp_t(u32, src_w, |
|---|
| 199 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 200 | | - CIF_ISP_INPUT_W_MAX_V12); |
|---|
| 201 | | - h = clamp_t(u32, src_h, |
|---|
| 202 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 203 | | - CIF_ISP_INPUT_H_MAX_V12); |
|---|
| 204 | | - } else if (dev->isp_ver == ISP_V13) { |
|---|
| 205 | | - w = clamp_t(u32, src_w, |
|---|
| 206 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 207 | | - CIF_ISP_INPUT_W_MAX_V13); |
|---|
| 208 | | - h = clamp_t(u32, src_h, |
|---|
| 209 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 210 | | - CIF_ISP_INPUT_H_MAX_V13); |
|---|
| 211 | | - } else if (dev->isp_ver == ISP_V21) { |
|---|
| 212 | | - w = clamp_t(u32, src_w, |
|---|
| 213 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 214 | | - CIF_ISP_INPUT_W_MAX_V21); |
|---|
| 215 | | - h = clamp_t(u32, src_h, |
|---|
| 216 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 217 | | - CIF_ISP_INPUT_H_MAX_V21); |
|---|
| 218 | | - } else { |
|---|
| 219 | | - w = clamp_t(u32, src_w, |
|---|
| 220 | | - CIF_ISP_INPUT_W_MIN, |
|---|
| 221 | | - CIF_ISP_INPUT_W_MAX); |
|---|
| 222 | | - h = clamp_t(u32, src_h, |
|---|
| 223 | | - CIF_ISP_INPUT_H_MIN, |
|---|
| 224 | | - CIF_ISP_INPUT_H_MAX); |
|---|
| 201 | + memset(&sel, 0, sizeof(sel)); |
|---|
| 202 | + switch (dev->isp_ver) { |
|---|
| 203 | + case ISP_V12: |
|---|
| 204 | + max_w = CIF_ISP_INPUT_W_MAX_V12; |
|---|
| 205 | + max_h = CIF_ISP_INPUT_H_MAX_V12; |
|---|
| 206 | + break; |
|---|
| 207 | + case ISP_V13: |
|---|
| 208 | + max_w = CIF_ISP_INPUT_W_MAX_V13; |
|---|
| 209 | + max_h = CIF_ISP_INPUT_H_MAX_V13; |
|---|
| 210 | + break; |
|---|
| 211 | + case ISP_V21: |
|---|
| 212 | + max_w = CIF_ISP_INPUT_W_MAX_V21; |
|---|
| 213 | + max_h = CIF_ISP_INPUT_H_MAX_V21; |
|---|
| 214 | + break; |
|---|
| 215 | + case ISP_V30: |
|---|
| 216 | + max_w = dev->hw_dev->unite ? |
|---|
| 217 | + CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30; |
|---|
| 218 | + max_h = dev->hw_dev->unite ? |
|---|
| 219 | + CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30; |
|---|
| 220 | + break; |
|---|
| 221 | + case ISP_V32: |
|---|
| 222 | + max_w = dev->hw_dev->unite ? |
|---|
| 223 | + CIF_ISP_INPUT_W_MAX_V32_UNITE : CIF_ISP_INPUT_W_MAX_V32; |
|---|
| 224 | + max_h = dev->hw_dev->unite ? |
|---|
| 225 | + CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; |
|---|
| 226 | + break; |
|---|
| 227 | + case ISP_V32_L: |
|---|
| 228 | + max_w = CIF_ISP_INPUT_W_MAX_V32_L; |
|---|
| 229 | + max_h = CIF_ISP_INPUT_H_MAX_V32_L; |
|---|
| 230 | + break; |
|---|
| 231 | + default: |
|---|
| 232 | + max_w = CIF_ISP_INPUT_W_MAX; |
|---|
| 233 | + max_h = CIF_ISP_INPUT_H_MAX; |
|---|
| 225 | 234 | } |
|---|
| 235 | + max_size = max_w * max_h; |
|---|
| 236 | + w = clamp_t(u32, src_w, CIF_ISP_INPUT_W_MIN, max_w); |
|---|
| 237 | + max_h = max_size / w; |
|---|
| 238 | + h = clamp_t(u32, src_h, CIF_ISP_INPUT_H_MIN, max_h); |
|---|
| 226 | 239 | |
|---|
| 227 | 240 | if (dev->active_sensor) |
|---|
| 228 | 241 | sensor = dev->active_sensor->sd; |
|---|
| .. | .. |
|---|
| 343 | 356 | return -ENODEV; |
|---|
| 344 | 357 | |
|---|
| 345 | 358 | sensor = sd_to_sensor(dev, sensor_sd); |
|---|
| 346 | | - ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config, |
|---|
| 347 | | - &sensor->mbus); |
|---|
| 359 | + if (!sensor) |
|---|
| 360 | + return -ENODEV; |
|---|
| 361 | + ret = v4l2_subdev_call(sensor->sd, pad, get_mbus_config, |
|---|
| 362 | + 0, &sensor->mbus); |
|---|
| 348 | 363 | if (ret && ret != -ENOIOCTLCMD) |
|---|
| 349 | 364 | return ret; |
|---|
| 350 | 365 | |
|---|
| 351 | | - if (sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 366 | + sensor->fmt[0].pad = 0; |
|---|
| 367 | + sensor->fmt[0].which = V4L2_SUBDEV_FORMAT_ACTIVE; |
|---|
| 368 | + ret = v4l2_subdev_call(sensor->sd, pad, get_fmt, |
|---|
| 369 | + &sensor->cfg, &sensor->fmt[0]); |
|---|
| 370 | + if (ret && ret != -ENOIOCTLCMD) |
|---|
| 371 | + return ret; |
|---|
| 372 | + |
|---|
| 373 | + if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY && |
|---|
| 374 | + dev->isp_ver < ISP_V30) { |
|---|
| 352 | 375 | u8 vc = 0; |
|---|
| 353 | 376 | |
|---|
| 354 | | - memset(dev->csi_dev.mipi_di, 0, |
|---|
| 355 | | - sizeof(dev->csi_dev.mipi_di)); |
|---|
| 356 | | - memset(sensor->fmt, 0, sizeof(sensor->fmt)); |
|---|
| 377 | + sensor_sd = get_remote_sensor(sensor->sd); |
|---|
| 378 | + if (!sensor_sd) |
|---|
| 379 | + return -ENODEV; |
|---|
| 380 | + memset(dev->csi_dev.mipi_di, 0, sizeof(dev->csi_dev.mipi_di)); |
|---|
| 357 | 381 | for (i = 0; i < dev->csi_dev.max_pad - 1; i++) { |
|---|
| 382 | + struct rkmodule_channel_info ch = { 0 }; |
|---|
| 383 | + |
|---|
| 358 | 384 | fmt = &sensor->fmt[i]; |
|---|
| 359 | | - fmt->pad = i; |
|---|
| 360 | | - fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE; |
|---|
| 361 | | - ret = v4l2_subdev_call(sensor->sd, pad, get_fmt, |
|---|
| 362 | | - &sensor->cfg, fmt); |
|---|
| 363 | | - if (ret && ret != -ENOIOCTLCMD) |
|---|
| 364 | | - return ret; |
|---|
| 385 | + ch.index = i; |
|---|
| 386 | + ret = v4l2_subdev_call(sensor_sd, core, ioctl, |
|---|
| 387 | + RKMODULE_GET_CHANNEL_INFO, &ch); |
|---|
| 388 | + if (ret) { |
|---|
| 389 | + if (i) |
|---|
| 390 | + *fmt = sensor->fmt[0]; |
|---|
| 391 | + } else { |
|---|
| 392 | + fmt->format.width = ch.width; |
|---|
| 393 | + fmt->format.height = ch.height; |
|---|
| 394 | + fmt->format.code = ch.bus_fmt; |
|---|
| 395 | + } |
|---|
| 365 | 396 | ret = mbus_pixelcode_to_mipi_dt(fmt->format.code); |
|---|
| 366 | 397 | if (ret < 0) { |
|---|
| 367 | 398 | v4l2_err(&dev->v4l2_dev, |
|---|
| 368 | 399 | "Invalid mipi data type\n"); |
|---|
| 369 | 400 | return ret; |
|---|
| 370 | 401 | } |
|---|
| 371 | | - /* v4l2_subdev_format reserved[0] |
|---|
| 372 | | - * using as mipi virtual channel |
|---|
| 373 | | - */ |
|---|
| 374 | | - switch (fmt->reserved[0]) { |
|---|
| 402 | + |
|---|
| 403 | + switch (ch.vc) { |
|---|
| 375 | 404 | case V4L2_MBUS_CSI2_CHANNEL_3: |
|---|
| 376 | 405 | vc = 3; |
|---|
| 377 | 406 | break; |
|---|
| .. | .. |
|---|
| 393 | 422 | fmt->format.width, |
|---|
| 394 | 423 | fmt->format.height); |
|---|
| 395 | 424 | } |
|---|
| 396 | | - } else { |
|---|
| 397 | | - sensor->fmt[0].pad = 0; |
|---|
| 398 | | - sensor->fmt[0].which = V4L2_SUBDEV_FORMAT_ACTIVE; |
|---|
| 399 | | - ret = v4l2_subdev_call(sensor->sd, pad, get_fmt, |
|---|
| 400 | | - &sensor->cfg, &sensor->fmt[0]); |
|---|
| 401 | | - if (ret && ret != -ENOIOCTLCMD) |
|---|
| 402 | | - return ret; |
|---|
| 403 | 425 | } |
|---|
| 404 | 426 | |
|---|
| 405 | 427 | v4l2_subdev_call(sensor->sd, video, g_frame_interval, &sensor->fi); |
|---|
| 406 | 428 | dev->active_sensor = sensor; |
|---|
| 407 | | - |
|---|
| 429 | + i = dev->dev_id; |
|---|
| 430 | + if (sensor->fi.interval.numerator) |
|---|
| 431 | + dev->hw_dev->isp_size[i].fps = |
|---|
| 432 | + sensor->fi.interval.denominator / sensor->fi.interval.numerator; |
|---|
| 408 | 433 | return ret; |
|---|
| 409 | 434 | } |
|---|
| 410 | 435 | |
|---|
| .. | .. |
|---|
| 471 | 496 | return pixelformat; |
|---|
| 472 | 497 | } |
|---|
| 473 | 498 | |
|---|
| 499 | +static void rkisp_dvfs(struct rkisp_device *dev) |
|---|
| 500 | +{ |
|---|
| 501 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 502 | + u64 data_rate = 0; |
|---|
| 503 | + int i, fps, num = 0; |
|---|
| 504 | + |
|---|
| 505 | + if (!hw->is_dvfs) |
|---|
| 506 | + return; |
|---|
| 507 | + hw->is_dvfs = false; |
|---|
| 508 | + for (i = 0; i < hw->dev_num; i++) { |
|---|
| 509 | + if (!hw->isp_size[i].is_on) |
|---|
| 510 | + continue; |
|---|
| 511 | + fps = hw->isp_size[i].fps; |
|---|
| 512 | + if (!fps) |
|---|
| 513 | + fps = 30; |
|---|
| 514 | + data_rate += (fps * hw->isp_size[i].size); |
|---|
| 515 | + num++; |
|---|
| 516 | + } |
|---|
| 517 | + do_div(data_rate, 1000 * 1000); |
|---|
| 518 | + /* increase margin: 25% * num */ |
|---|
| 519 | + data_rate += (data_rate >> 2) * num; |
|---|
| 520 | + /* one frame two-run, data double */ |
|---|
| 521 | + if (hw->is_multi_overflow && num > 1) |
|---|
| 522 | + data_rate *= 2; |
|---|
| 523 | + /* compare with isp clock adjustment table */ |
|---|
| 524 | + for (i = 0; i < hw->num_clk_rate_tbl; i++) |
|---|
| 525 | + if (data_rate <= hw->clk_rate_tbl[i].clk_rate) |
|---|
| 526 | + break; |
|---|
| 527 | + if (i == hw->num_clk_rate_tbl) |
|---|
| 528 | + i--; |
|---|
| 529 | + |
|---|
| 530 | + /* set isp clock rate */ |
|---|
| 531 | + rkisp_set_clk_rate(hw->clks[0], hw->clk_rate_tbl[i].clk_rate * 1000000UL); |
|---|
| 532 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 533 | + rkisp_set_clk_rate(hw->clks[5], hw->clk_rate_tbl[i].clk_rate * 1000000UL); |
|---|
| 534 | + /* aclk equal to core clk */ |
|---|
| 535 | + if (dev->isp_ver == ISP_V32) |
|---|
| 536 | + rkisp_set_clk_rate(hw->clks[1], hw->clk_rate_tbl[i].clk_rate * 1000000UL); |
|---|
| 537 | + dev_info(hw->dev, "set isp clk = %luHz\n", clk_get_rate(hw->clks[0])); |
|---|
| 538 | +} |
|---|
| 539 | + |
|---|
| 540 | +static void rkisp_multi_overflow_hdl(struct rkisp_device *dev, bool on) |
|---|
| 541 | +{ |
|---|
| 542 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 543 | + |
|---|
| 544 | + if (on) { |
|---|
| 545 | + /* enable mi */ |
|---|
| 546 | + rkisp_update_regs(dev, ISP3X_MI_WR_CTRL, ISP3X_MI_WR_CTRL); |
|---|
| 547 | + rkisp_update_regs(dev, ISP3X_ISP_CTRL1, ISP3X_ISP_CTRL1); |
|---|
| 548 | + if (dev->isp_ver == ISP_V30) { |
|---|
| 549 | + rkisp_update_regs(dev, ISP3X_MPFBC_CTRL, ISP3X_MPFBC_CTRL); |
|---|
| 550 | + rkisp_update_regs(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_MI_BP_WR_CTRL); |
|---|
| 551 | + rkisp_update_regs(dev, ISP3X_SWS_CFG, ISP3X_SWS_CFG); |
|---|
| 552 | + } else if (dev->isp_ver == ISP_V32) { |
|---|
| 553 | + rkisp_update_regs(dev, ISP3X_MI_BP_WR_CTRL, ISP3X_MI_BP_WR_CTRL); |
|---|
| 554 | + rkisp_update_regs(dev, ISP32_MI_BPDS_WR_CTRL, ISP32_MI_BPDS_WR_CTRL); |
|---|
| 555 | + rkisp_update_regs(dev, ISP32_MI_MPDS_WR_CTRL, ISP32_MI_MPDS_WR_CTRL); |
|---|
| 556 | + } |
|---|
| 557 | + } else { |
|---|
| 558 | + /* disabled mi. rv1106 sdmmc workaround, 3a_wr no close */ |
|---|
| 559 | + writel(CIF_MI_CTRL_INIT_OFFSET_EN | CIF_MI_CTRL_INIT_BASE_EN, |
|---|
| 560 | + hw->base_addr + ISP3X_MI_WR_CTRL); |
|---|
| 561 | + if (dev->isp_ver == ISP_V30) { |
|---|
| 562 | + writel(0, hw->base_addr + ISP3X_MPFBC_CTRL); |
|---|
| 563 | + writel(0, hw->base_addr + ISP3X_MI_BP_WR_CTRL); |
|---|
| 564 | + writel(0xc, hw->base_addr + ISP3X_SWS_CFG); |
|---|
| 565 | + if (hw->unite == ISP_UNITE_TWO) { |
|---|
| 566 | + writel(0, hw->base_next_addr + ISP3X_MI_WR_CTRL); |
|---|
| 567 | + writel(0, hw->base_next_addr + ISP3X_MPFBC_CTRL); |
|---|
| 568 | + writel(0, hw->base_next_addr + ISP3X_MI_BP_WR_CTRL); |
|---|
| 569 | + writel(0xc, hw->base_next_addr + ISP3X_SWS_CFG); |
|---|
| 570 | + } |
|---|
| 571 | + } else if (dev->isp_ver == ISP_V32) { |
|---|
| 572 | + writel(0, hw->base_addr + ISP3X_MI_BP_WR_CTRL); |
|---|
| 573 | + writel(0, hw->base_addr + ISP32_MI_BPDS_WR_CTRL); |
|---|
| 574 | + writel(0, hw->base_addr + ISP32_MI_MPDS_WR_CTRL); |
|---|
| 575 | + } |
|---|
| 576 | + } |
|---|
| 577 | + rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true); |
|---|
| 578 | +} |
|---|
| 474 | 579 | |
|---|
| 475 | 580 | /* |
|---|
| 476 | 581 | * for hdr read back mode, rawrd read back data |
|---|
| .. | .. |
|---|
| 479 | 584 | void rkisp_trigger_read_back(struct rkisp_device *dev, u8 dma2frm, u32 mode, bool is_try) |
|---|
| 480 | 585 | { |
|---|
| 481 | 586 | struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev; |
|---|
| 587 | + struct rkisp_isp_stats_vdev *stats_vdev = &dev->stats_vdev; |
|---|
| 482 | 588 | struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 483 | 589 | u32 val, cur_frame_id, tmp, rd_mode; |
|---|
| 484 | 590 | u64 iq_feature = hw->iq_feature; |
|---|
| .. | .. |
|---|
| 488 | 594 | hw->cur_dev_id = dev->dev_id; |
|---|
| 489 | 595 | rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, NULL, true); |
|---|
| 490 | 596 | |
|---|
| 597 | + /* isp process the same frame */ |
|---|
| 598 | + if (is_try) |
|---|
| 599 | + goto run_next; |
|---|
| 600 | + |
|---|
| 491 | 601 | val = 0; |
|---|
| 492 | | - if (mode & T_START_X1) { |
|---|
| 602 | + if (mode & (T_START_X1 | T_START_C)) { |
|---|
| 493 | 603 | rd_mode = HDR_RDBK_FRAME1; |
|---|
| 494 | 604 | } else if (mode & T_START_X2) { |
|---|
| 495 | 605 | rd_mode = HDR_RDBK_FRAME2; |
|---|
| .. | .. |
|---|
| 502 | 612 | val = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf; |
|---|
| 503 | 613 | } |
|---|
| 504 | 614 | |
|---|
| 615 | + if (mode & T_START_C) |
|---|
| 616 | + rkisp_expander_config(dev, NULL, true); |
|---|
| 617 | + else |
|---|
| 618 | + rkisp_expander_config(dev, NULL, false); |
|---|
| 619 | + |
|---|
| 505 | 620 | if (is_feature_on) { |
|---|
| 506 | 621 | if ((ISP2X_MODULE_HDRMGE & ~iq_feature) && (val & SW_HDRMGE_EN)) { |
|---|
| 507 | 622 | v4l2_err(&dev->v4l2_dev, "hdrmge is not supported\n"); |
|---|
| .. | .. |
|---|
| 509 | 624 | } |
|---|
| 510 | 625 | } |
|---|
| 511 | 626 | |
|---|
| 512 | | - tmp = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf; |
|---|
| 513 | | - if (val != tmp) { |
|---|
| 514 | | - rkisp_write(dev, ISP_HDRMGE_BASE, val, false); |
|---|
| 627 | + if (rd_mode != dev->rd_mode) { |
|---|
| 628 | + rkisp_unite_set_bits(dev, ISP_HDRMGE_BASE, ISP_HDRMGE_MODE_MASK, val, false); |
|---|
| 515 | 629 | dev->skip_frame = 2; |
|---|
| 516 | 630 | is_upd = true; |
|---|
| 517 | 631 | } |
|---|
| 518 | 632 | |
|---|
| 519 | | - if (dev->isp_ver == ISP_V20 && dev->dmarx_dev.trigger == T_MANUAL && !is_try) { |
|---|
| 520 | | - if (dev->rd_mode != rd_mode && RKMODULE_EXTEND_LINE != 0) { |
|---|
| 633 | + if (dev->isp_ver == ISP_V20 && dev->dmarx_dev.trigger == T_MANUAL) { |
|---|
| 634 | + if (dev->rd_mode != rd_mode && dev->br_dev.en) { |
|---|
| 521 | 635 | tmp = dev->isp_sdev.in_crop.height; |
|---|
| 522 | 636 | val = rkisp_read(dev, CIF_DUAL_CROP_CTRL, false); |
|---|
| 523 | 637 | if (rd_mode == HDR_RDBK_FRAME1) { |
|---|
| 524 | | - val |= CIF_DUAL_CROP_MP_MODE_YUV | CIF_DUAL_CROP_SP_MODE_YUV; |
|---|
| 638 | + val |= CIF_DUAL_CROP_MP_MODE_YUV; |
|---|
| 525 | 639 | tmp += RKMODULE_EXTEND_LINE; |
|---|
| 526 | 640 | } else { |
|---|
| 527 | | - val &= ~(CIF_DUAL_CROP_MP_MODE_YUV | CIF_DUAL_CROP_SP_MODE_YUV); |
|---|
| 641 | + val &= ~CIF_DUAL_CROP_MP_MODE_YUV; |
|---|
| 528 | 642 | } |
|---|
| 529 | | - val |= CIF_DUAL_CROP_CFG_UPD; |
|---|
| 530 | 643 | rkisp_write(dev, CIF_DUAL_CROP_CTRL, val, false); |
|---|
| 531 | 644 | rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, tmp, false); |
|---|
| 532 | 645 | rkisp_write(dev, CIF_ISP_OUT_V_SIZE, tmp, false); |
|---|
| .. | .. |
|---|
| 538 | 651 | } |
|---|
| 539 | 652 | dev->rd_mode = rd_mode; |
|---|
| 540 | 653 | |
|---|
| 541 | | - rkisp_params_first_cfg(&dev->params_vdev, &dev->isp_sdev.in_fmt, |
|---|
| 542 | | - dev->isp_sdev.quantization); |
|---|
| 543 | | - rkisp_params_cfg(params_vdev, cur_frame_id); |
|---|
| 654 | + if (hw->unite != ISP_UNITE_ONE || dev->unite_index == ISP_UNITE_LEFT) { |
|---|
| 655 | + rkisp_params_first_cfg(&dev->params_vdev, &dev->isp_sdev.in_fmt, |
|---|
| 656 | + dev->isp_sdev.quantization); |
|---|
| 657 | + rkisp_params_cfg(params_vdev, cur_frame_id); |
|---|
| 658 | + rkisp_config_cmsk(dev); |
|---|
| 659 | + rkisp_stream_frame_start(dev, 0); |
|---|
| 660 | + } |
|---|
| 544 | 661 | |
|---|
| 545 | | - if (!hw->is_single && !is_try) { |
|---|
| 662 | + if (!hw->is_single) { |
|---|
| 663 | + /* multi sensor need to reset isp resize mode if scale up */ |
|---|
| 664 | + val = 0; |
|---|
| 665 | + if (rkisp_read(dev, ISP3X_MAIN_RESIZE_CTRL, true) & 0xf0) |
|---|
| 666 | + val |= BIT(3); |
|---|
| 667 | + if (dev->isp_ver != ISP_V32_L && |
|---|
| 668 | + rkisp_read(dev, ISP3X_SELF_RESIZE_CTRL, true) & 0xf0) |
|---|
| 669 | + val |= BIT(4); |
|---|
| 670 | + if (rkisp_read(dev, ISP32_BP_RESIZE_CTRL, true) & 0xf0) |
|---|
| 671 | + val |= BIT(12); |
|---|
| 672 | + if (val) { |
|---|
| 673 | + writel(val, hw->base_addr + CIF_IRCL); |
|---|
| 674 | + writel(0, hw->base_addr + CIF_IRCL); |
|---|
| 675 | + } |
|---|
| 676 | + |
|---|
| 546 | 677 | rkisp_update_regs(dev, CTRL_VI_ISP_PATH, SUPER_IMP_COLOR_CR); |
|---|
| 547 | | - rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, DUAL_CROP_S_V_SIZE); |
|---|
| 548 | | - rkisp_update_regs(dev, ISP_ACQ_PROP, DUAL_CROP_CTRL); |
|---|
| 549 | | - rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, MI_WR_CTRL); |
|---|
| 550 | | - rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, MAIN_RESIZE_CTRL); |
|---|
| 551 | | - rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, SELF_RESIZE_CTRL); |
|---|
| 678 | + rkisp_update_regs(dev, DUAL_CROP_M_H_OFFS, ISP3X_DUAL_CROP_FBC_V_SIZE); |
|---|
| 679 | + rkisp_update_regs(dev, ISP_ACQ_H_OFFS, DUAL_CROP_CTRL); |
|---|
| 680 | + rkisp_update_regs(dev, SELF_RESIZE_SCALE_HY, MI_WR_CTRL); |
|---|
| 681 | + rkisp_update_regs(dev, ISP32_BP_RESIZE_SCALE_HY, SELF_RESIZE_CTRL); |
|---|
| 682 | + rkisp_update_regs(dev, MAIN_RESIZE_SCALE_HY, ISP32_BP_RESIZE_CTRL); |
|---|
| 683 | + rkisp_update_regs(dev, ISP_GAMMA_OUT_CTRL, MAIN_RESIZE_CTRL); |
|---|
| 552 | 684 | rkisp_update_regs(dev, MI_RD_CTRL2, ISP_LSC_CTRL); |
|---|
| 553 | | - rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_MP_WR_Y_LLENGTH); |
|---|
| 685 | + rkisp_update_regs(dev, MI_MP_WR_Y_BASE, MI_WR_CTRL2 - 4); |
|---|
| 554 | 686 | rkisp_update_regs(dev, ISP_LSC_XGRAD_01, ISP_RAWAWB_RAM_DATA); |
|---|
| 555 | 687 | if (dev->isp_ver == ISP_V20 && |
|---|
| 556 | 688 | (rkisp_read(dev, ISP_DHAZ_CTRL, false) & ISP_DHAZ_ENMUX || |
|---|
| .. | .. |
|---|
| 560 | 692 | val = rkisp_read(dev, MI_WR_CTRL2, false); |
|---|
| 561 | 693 | rkisp_set_bits(dev, MI_WR_CTRL2, 0, val, true); |
|---|
| 562 | 694 | rkisp_write(dev, MI_WR_INIT, ISP21_SP_FORCE_UPD | ISP21_MP_FORCE_UPD, true); |
|---|
| 563 | | - /* sensor mode & index */ |
|---|
| 695 | + } else { |
|---|
| 696 | + if (dev->isp_ver == ISP_V32_L) |
|---|
| 697 | + rkisp_write(dev, ISP32_SELF_SCALE_UPDATE, ISP32_SCALE_FORCE_UPD, true); |
|---|
| 698 | + rkisp_unite_write(dev, ISP3X_MI_WR_INIT, CIF_MI_INIT_SOFT_UPD, true); |
|---|
| 699 | + } |
|---|
| 700 | + /* sensor mode & index */ |
|---|
| 701 | + if (dev->isp_ver >= ISP_V21) { |
|---|
| 564 | 702 | val = rkisp_read_reg_cache(dev, ISP_ACQ_H_OFFS); |
|---|
| 565 | | - val |= ISP21_SENSOR_MODE(hw->dev_num >= 3 ? 2 : hw->dev_num - 1) | |
|---|
| 566 | | - ISP21_SENSOR_INDEX(dev->dev_id); |
|---|
| 703 | + val |= ISP21_SENSOR_INDEX(dev->multi_index); |
|---|
| 704 | + if (dev->isp_ver == ISP_V32_L) |
|---|
| 705 | + val |= ISP32L_SENSOR_MODE(dev->multi_mode); |
|---|
| 706 | + else |
|---|
| 707 | + val |= ISP21_SENSOR_MODE(dev->multi_mode); |
|---|
| 567 | 708 | writel(val, hw->base_addr + ISP_ACQ_H_OFFS); |
|---|
| 709 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 710 | + writel(val, hw->base_next_addr + ISP_ACQ_H_OFFS); |
|---|
| 711 | + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 712 | + "sensor mode:%d index:%d | 0x%x\n", |
|---|
| 713 | + dev->multi_mode, dev->multi_index, val); |
|---|
| 568 | 714 | } |
|---|
| 569 | 715 | is_upd = true; |
|---|
| 570 | 716 | } |
|---|
| 571 | 717 | |
|---|
| 572 | | - if (dev->isp_ver == ISP_V21) |
|---|
| 718 | + if (dev->isp_ver > ISP_V20) |
|---|
| 573 | 719 | dma2frm = 0; |
|---|
| 574 | 720 | if (dma2frm > 2) |
|---|
| 575 | 721 | dma2frm = 2; |
|---|
| 576 | 722 | if (dma2frm == 2) |
|---|
| 577 | 723 | dev->rdbk_cnt_x3++; |
|---|
| 578 | | - else if (dma2frm == 1) |
|---|
| 724 | + else if (dma2frm == 1 || dev->sw_rd_cnt) |
|---|
| 579 | 725 | dev->rdbk_cnt_x2++; |
|---|
| 580 | 726 | else |
|---|
| 581 | 727 | dev->rdbk_cnt_x1++; |
|---|
| 582 | 728 | dev->rdbk_cnt++; |
|---|
| 729 | + if (dev->isp_ver == ISP_V20) |
|---|
| 730 | + params_vdev->rdbk_times = dma2frm + 1; |
|---|
| 583 | 731 | |
|---|
| 732 | +run_next: |
|---|
| 584 | 733 | rkisp_params_cfgsram(params_vdev); |
|---|
| 585 | | - params_vdev->rdbk_times = dma2frm + 1; |
|---|
| 734 | + stats_vdev->rdbk_drop = false; |
|---|
| 735 | + if (dev->is_frame_double) { |
|---|
| 736 | + is_upd = true; |
|---|
| 737 | + if (is_try) { |
|---|
| 738 | + /* the frame second running to on mi */ |
|---|
| 739 | + rkisp_multi_overflow_hdl(dev, true); |
|---|
| 740 | + rkisp_update_regs(dev, ISP_LDCH_BASE, ISP_LDCH_BASE); |
|---|
| 586 | 741 | |
|---|
| 587 | | - /* read 3d lut at frame end */ |
|---|
| 742 | + val = ISP3X_YNR_FST_FRAME | ISP3X_DHAZ_FST_FRAME | ISP3X_CNR_FST_FRAME; |
|---|
| 743 | + if (dev->isp_ver == ISP_V32) |
|---|
| 744 | + val |= ISP32_SHP_FST_FRAME; |
|---|
| 745 | + else |
|---|
| 746 | + val |= ISP3X_CNR_FST_FRAME; |
|---|
| 747 | + rkisp_unite_clear_bits(dev, ISP3X_ISP_CTRL1, val, false); |
|---|
| 748 | + val = rkisp_read_reg_cache(dev, ISP3X_DRC_IIRWG_GAIN); |
|---|
| 749 | + writel(val, hw->base_addr + ISP3X_DRC_IIRWG_GAIN); |
|---|
| 750 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 751 | + writel(val, hw->base_next_addr + ISP3X_DRC_IIRWG_GAIN); |
|---|
| 752 | + val = rkisp_read_reg_cache(dev, ISP3X_DRC_EXPLRATIO); |
|---|
| 753 | + writel(val, hw->base_addr + ISP3X_DRC_EXPLRATIO); |
|---|
| 754 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 755 | + writel(val, hw->base_next_addr + ISP3X_DRC_EXPLRATIO); |
|---|
| 756 | + } else { |
|---|
| 757 | + /* the frame first running to off mi to save bandwidth */ |
|---|
| 758 | + rkisp_multi_overflow_hdl(dev, false); |
|---|
| 759 | + |
|---|
| 760 | + /* FST_FRAME no to read sram thumb */ |
|---|
| 761 | + val = ISP3X_YNR_FST_FRAME | ISP3X_DHAZ_FST_FRAME; |
|---|
| 762 | + if (dev->isp_ver == ISP_V32) |
|---|
| 763 | + val |= ISP32_SHP_FST_FRAME; |
|---|
| 764 | + else |
|---|
| 765 | + val |= ISP3X_CNR_FST_FRAME; |
|---|
| 766 | + rkisp_unite_set_bits(dev, ISP3X_ISP_CTRL1, 0, val, false); |
|---|
| 767 | + /* ADRC low iir thumb weight for first sensor switch */ |
|---|
| 768 | + val = rkisp_read_reg_cache(dev, ISP3X_DRC_IIRWG_GAIN); |
|---|
| 769 | + val &= ~ISP3X_DRC_IIR_WEIGHT_MASK; |
|---|
| 770 | + writel(val, hw->base_addr + ISP3X_DRC_IIRWG_GAIN); |
|---|
| 771 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 772 | + writel(val, hw->base_next_addr + ISP3X_DRC_IIRWG_GAIN); |
|---|
| 773 | + /* ADRC iir5x5 and cur3x3 weight */ |
|---|
| 774 | + val = rkisp_read_reg_cache(dev, ISP3X_DRC_EXPLRATIO); |
|---|
| 775 | + val &= ~ISP3X_DRC_WEIPRE_FRAME_MASK; |
|---|
| 776 | + writel(val, hw->base_addr + ISP3X_DRC_EXPLRATIO); |
|---|
| 777 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 778 | + writel(val, hw->base_next_addr + ISP3X_DRC_EXPLRATIO); |
|---|
| 779 | + /* YNR_THUMB_MIX_CUR_EN for thumb read addr to 0 */ |
|---|
| 780 | + val = rkisp_read_reg_cache(dev, ISP3X_YNR_GLOBAL_CTRL); |
|---|
| 781 | + val |= ISP3X_YNR_THUMB_MIX_CUR_EN; |
|---|
| 782 | + writel(val, hw->base_addr + ISP3X_YNR_GLOBAL_CTRL); |
|---|
| 783 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 784 | + writel(val, hw->base_next_addr + ISP3X_YNR_GLOBAL_CTRL); |
|---|
| 785 | + if (dev->isp_ver == ISP_V21 || dev->isp_ver == ISP_V30) { |
|---|
| 786 | + /* CNR_THUMB_MIX_CUR_EN for thumb read addr to 0 */ |
|---|
| 787 | + val = rkisp_read_reg_cache(dev, ISP3X_CNR_CTRL); |
|---|
| 788 | + val |= ISP3X_CNR_THUMB_MIX_CUR_EN; |
|---|
| 789 | + writel(val, hw->base_addr + ISP3X_CNR_CTRL); |
|---|
| 790 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 791 | + writel(val, hw->base_next_addr + ISP3X_CNR_CTRL); |
|---|
| 792 | + } |
|---|
| 793 | + stats_vdev->rdbk_drop = true; |
|---|
| 794 | + } |
|---|
| 795 | + } |
|---|
| 796 | + |
|---|
| 797 | + /* disable isp force update to read 3dlut |
|---|
| 798 | + * 3dlut auto update at frame end for single sensor |
|---|
| 799 | + */ |
|---|
| 588 | 800 | if (hw->is_single && is_upd && |
|---|
| 589 | 801 | rkisp_read_reg_cache(dev, ISP_3DLUT_UPDATE) & 0x1) { |
|---|
| 590 | | - rkisp_write(dev, ISP_3DLUT_UPDATE, 0, true); |
|---|
| 802 | + rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 0, true); |
|---|
| 591 | 803 | is_3dlut_upd = true; |
|---|
| 592 | 804 | } |
|---|
| 593 | 805 | if (is_upd) { |
|---|
| 594 | 806 | val = rkisp_read(dev, ISP_CTRL, false); |
|---|
| 595 | 807 | val |= CIF_ISP_CTRL_ISP_CFG_UPD; |
|---|
| 596 | | - rkisp_write(dev, ISP_CTRL, val, true); |
|---|
| 808 | + rkisp_unite_write(dev, ISP_CTRL, val, true); |
|---|
| 809 | + /* bayer pat after ISP_CFG_UPD for multi sensor to read lsc r/g/b table */ |
|---|
| 810 | + rkisp_update_regs(dev, ISP3X_ISP_CTRL1, ISP3X_ISP_CTRL1); |
|---|
| 597 | 811 | /* fix ldch multi sensor case: |
|---|
| 598 | 812 | * ldch will pre-read data when en and isp force upd or frame end, |
|---|
| 599 | 813 | * udelay for ldch pre-read data. |
|---|
| 600 | 814 | * ldch en=0 before start for frame end to stop ldch read data. |
|---|
| 601 | 815 | */ |
|---|
| 602 | | - if (!hw->is_single && |
|---|
| 603 | | - (rkisp_read(dev, ISP_LDCH_BASE, true) & 0x1)) { |
|---|
| 816 | + val = rkisp_read(dev, ISP_LDCH_BASE, true); |
|---|
| 817 | + if (!hw->is_single && val & BIT(0)) { |
|---|
| 604 | 818 | udelay(50); |
|---|
| 605 | | - writel(0, hw->base_addr + ISP_LDCH_BASE); |
|---|
| 819 | + val &= ~(BIT(0) | BIT(31)); |
|---|
| 820 | + writel(val, hw->base_addr + ISP_LDCH_BASE); |
|---|
| 821 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 822 | + writel(val, hw->base_next_addr + ISP_LDCH_BASE); |
|---|
| 606 | 823 | } |
|---|
| 607 | 824 | } |
|---|
| 608 | 825 | if (is_3dlut_upd) |
|---|
| 609 | | - rkisp_write(dev, ISP_3DLUT_UPDATE, 1, true); |
|---|
| 826 | + rkisp_unite_write(dev, ISP_3DLUT_UPDATE, 1, true); |
|---|
| 610 | 827 | |
|---|
| 611 | 828 | /* if output stream enable, wait it end */ |
|---|
| 612 | 829 | val = rkisp_read(dev, CIF_MI_CTRL_SHD, true); |
|---|
| .. | .. |
|---|
| 618 | 835 | dev->irq_ends_mask |= ISP_FRAME_SP; |
|---|
| 619 | 836 | else |
|---|
| 620 | 837 | dev->irq_ends_mask &= ~ISP_FRAME_SP; |
|---|
| 621 | | - |
|---|
| 622 | | - memset(dev->filt_state, 0, sizeof(dev->filt_state)); |
|---|
| 623 | | - dev->filt_state[RDBK_F_VS] = dma2frm; |
|---|
| 838 | + if ((dev->isp_ver == ISP_V20 && |
|---|
| 839 | + rkisp_read(dev, ISP_MPFBC_CTRL, true) & SW_MPFBC_EN) || |
|---|
| 840 | + (dev->isp_ver == ISP_V30 && |
|---|
| 841 | + rkisp_read(dev, ISP3X_MPFBC_CTRL, true) & ISP3X_MPFBC_EN_SHD)) |
|---|
| 842 | + dev->irq_ends_mask |= ISP_FRAME_MPFBC; |
|---|
| 843 | + else |
|---|
| 844 | + dev->irq_ends_mask &= ~ISP_FRAME_MPFBC; |
|---|
| 845 | + if ((dev->isp_ver == ISP_V30 && |
|---|
| 846 | + rkisp_read(dev, ISP3X_MI_BP_WR_CTRL, true) & ISP3X_BP_ENABLE) || |
|---|
| 847 | + (dev->isp_ver == ISP_V32 && |
|---|
| 848 | + rkisp_read(dev, ISP32_MI_WR_CTRL2_SHD, true) & ISP32_BP_EN_OUT_SHD)) |
|---|
| 849 | + dev->irq_ends_mask |= ISP_FRAME_BP; |
|---|
| 850 | + else |
|---|
| 851 | + dev->irq_ends_mask &= ~ISP_FRAME_BP; |
|---|
| 624 | 852 | |
|---|
| 625 | 853 | val = rkisp_read(dev, CSI2RX_CTRL0, true); |
|---|
| 626 | 854 | val &= ~SW_IBUF_OP_MODE(0xf); |
|---|
| 627 | 855 | tmp = SW_IBUF_OP_MODE(dev->rd_mode); |
|---|
| 628 | 856 | val |= tmp | SW_CSI2RX_EN | SW_DMA_2FRM_MODE(dma2frm); |
|---|
| 857 | + if (dev->isp_ver > ISP_V20) |
|---|
| 858 | + dma2frm = dev->sw_rd_cnt; |
|---|
| 629 | 859 | v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 630 | | - "readback frame:%d time:%d 0x%x\n", |
|---|
| 631 | | - cur_frame_id, dma2frm + 1, val); |
|---|
| 632 | | - if (!dma2frm) |
|---|
| 633 | | - rkisp_bridge_update_mi(dev, 0); |
|---|
| 860 | + "readback frame:%d time:%d 0x%x try:%d\n", |
|---|
| 861 | + cur_frame_id, dma2frm + 1, val, is_try); |
|---|
| 634 | 862 | if (!hw->is_shutdown) |
|---|
| 635 | | - rkisp_write(dev, CSI2RX_CTRL0, val, true); |
|---|
| 863 | + rkisp_unite_write(dev, CSI2RX_CTRL0, val, true); |
|---|
| 864 | +} |
|---|
| 865 | + |
|---|
| 866 | +static void rkisp_fast_switch_rx_buf(struct rkisp_device *dev, bool is_current) |
|---|
| 867 | +{ |
|---|
| 868 | + struct rkisp_stream *stream; |
|---|
| 869 | + struct rkisp_buffer *buf; |
|---|
| 870 | + u32 i, val; |
|---|
| 871 | + |
|---|
| 872 | + for (i = RKISP_STREAM_RAWRD0; i < RKISP_MAX_DMARX_STREAM; i++) { |
|---|
| 873 | + stream = &dev->dmarx_dev.stream[i]; |
|---|
| 874 | + if (!stream->ops) |
|---|
| 875 | + continue; |
|---|
| 876 | + buf = NULL; |
|---|
| 877 | + if (is_current) |
|---|
| 878 | + buf = stream->curr_buf; |
|---|
| 879 | + else if (!list_empty(&stream->buf_queue)) |
|---|
| 880 | + buf = list_first_entry(&stream->buf_queue, |
|---|
| 881 | + struct rkisp_buffer, queue); |
|---|
| 882 | + if (!buf) |
|---|
| 883 | + continue; |
|---|
| 884 | + val = buf->buff_addr[RKISP_PLANE_Y]; |
|---|
| 885 | + /* f1 -> f0 -> f1 for normal |
|---|
| 886 | + * L:f1 L:f1 -> L:f0 S:f0 -> L:f1 S:f1 for hdr2 |
|---|
| 887 | + */ |
|---|
| 888 | + if (dev->rd_mode == HDR_RDBK_FRAME2 && !is_current && |
|---|
| 889 | + rkisp_read_reg_cache(dev, ISP3X_HDRMGE_GAIN0) == 0xfff0040) { |
|---|
| 890 | + if (i == RKISP_STREAM_RAWRD2) |
|---|
| 891 | + continue; |
|---|
| 892 | + else |
|---|
| 893 | + rkisp_write(dev, ISP3X_MI_RAWS_RD_BASE, val, false); |
|---|
| 894 | + } |
|---|
| 895 | + rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); |
|---|
| 896 | + } |
|---|
| 636 | 897 | } |
|---|
| 637 | 898 | |
|---|
| 638 | 899 | static void rkisp_rdbk_trigger_handle(struct rkisp_device *dev, u32 cmd) |
|---|
| .. | .. |
|---|
| 644 | 905 | int i, times = -1, max = 0, id = 0; |
|---|
| 645 | 906 | int len[DEV_MAX] = { 0 }; |
|---|
| 646 | 907 | u32 mode = 0; |
|---|
| 908 | + bool is_try = false; |
|---|
| 647 | 909 | |
|---|
| 648 | 910 | spin_lock_irqsave(&hw->rdbk_lock, lock_flags); |
|---|
| 649 | | - if (cmd == T_CMD_END) |
|---|
| 911 | + if (cmd == T_CMD_END) { |
|---|
| 912 | + if (dev->sw_rd_cnt) { |
|---|
| 913 | + dev->sw_rd_cnt--; |
|---|
| 914 | + isp = dev; |
|---|
| 915 | + is_try = true; |
|---|
| 916 | + times = 0; |
|---|
| 917 | + if (hw->unite == ISP_UNITE_ONE) { |
|---|
| 918 | + if (dev->sw_rd_cnt < 2) |
|---|
| 919 | + isp->unite_index = ISP_UNITE_RIGHT; |
|---|
| 920 | + if (!hw->is_multi_overflow || (dev->sw_rd_cnt & 0x1)) |
|---|
| 921 | + is_try = false; |
|---|
| 922 | + } |
|---|
| 923 | + goto end; |
|---|
| 924 | + } |
|---|
| 650 | 925 | hw->is_idle = true; |
|---|
| 926 | + hw->pre_dev_id = dev->dev_id; |
|---|
| 927 | + } |
|---|
| 651 | 928 | if (hw->is_shutdown) |
|---|
| 652 | 929 | hw->is_idle = false; |
|---|
| 653 | 930 | if (!hw->is_idle) |
|---|
| 654 | 931 | goto end; |
|---|
| 655 | 932 | if (hw->monitor.state & ISP_MIPI_ERROR && hw->monitor.is_en) |
|---|
| 656 | 933 | goto end; |
|---|
| 934 | + if (!IS_HDR_RDBK(dev->rd_mode)) |
|---|
| 935 | + goto end; |
|---|
| 657 | 936 | |
|---|
| 658 | 937 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 659 | 938 | isp = hw->isp[i]; |
|---|
| 660 | | - if (!(isp->isp_state & ISP_START)) |
|---|
| 939 | + if (!isp || |
|---|
| 940 | + (isp && !(isp->isp_state & ISP_START))) |
|---|
| 661 | 941 | continue; |
|---|
| 662 | 942 | rkisp_rdbk_trigger_event(isp, T_CMD_LEN, &len[i]); |
|---|
| 663 | 943 | if (max < len[i]) { |
|---|
| .. | .. |
|---|
| 666 | 946 | } |
|---|
| 667 | 947 | } |
|---|
| 668 | 948 | |
|---|
| 949 | + /* wait 2 frame to start isp for fast */ |
|---|
| 950 | + if (dev->is_pre_on && max == 1 && !atomic_read(&dev->isp_sdev.frm_sync_seq)) |
|---|
| 951 | + goto end; |
|---|
| 952 | + |
|---|
| 669 | 953 | if (max) { |
|---|
| 670 | | - v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 671 | | - "trigger fifo len:%d\n", max); |
|---|
| 672 | 954 | isp = hw->isp[id]; |
|---|
| 955 | + v4l2_dbg(2, rkisp_debug, &isp->v4l2_dev, |
|---|
| 956 | + "trigger fifo len:%d\n", max); |
|---|
| 673 | 957 | rkisp_rdbk_trigger_event(isp, T_CMD_DEQUEUE, &t); |
|---|
| 674 | 958 | isp->dmarx_dev.pre_frame = isp->dmarx_dev.cur_frame; |
|---|
| 675 | 959 | if (t.frame_id > isp->dmarx_dev.pre_frame.id && |
|---|
| .. | .. |
|---|
| 680 | 964 | isp->dmarx_dev.cur_frame.sof_timestamp = t.sof_timestamp; |
|---|
| 681 | 965 | isp->dmarx_dev.cur_frame.timestamp = t.frame_timestamp; |
|---|
| 682 | 966 | isp->isp_sdev.frm_timestamp = t.sof_timestamp; |
|---|
| 967 | + atomic_set(&isp->isp_sdev.frm_sync_seq, t.frame_id + 1); |
|---|
| 683 | 968 | mode = t.mode; |
|---|
| 684 | 969 | times = t.times; |
|---|
| 685 | 970 | hw->cur_dev_id = id; |
|---|
| 686 | 971 | hw->is_idle = false; |
|---|
| 972 | + /* this frame will read count by isp */ |
|---|
| 973 | + isp->sw_rd_cnt = 0; |
|---|
| 974 | + /* frame double for multi camera resolution out of hardware limit |
|---|
| 975 | + * first for HW save this camera information, and second to output image |
|---|
| 976 | + */ |
|---|
| 977 | + isp->is_frame_double = false; |
|---|
| 978 | + if (hw->is_multi_overflow && |
|---|
| 979 | + (hw->unite == ISP_UNITE_ONE || |
|---|
| 980 | + (hw->pre_dev_id != -1 && hw->pre_dev_id != id))) { |
|---|
| 981 | + isp->is_frame_double = true; |
|---|
| 982 | + isp->sw_rd_cnt = 1; |
|---|
| 983 | + times = 0; |
|---|
| 984 | + } |
|---|
| 985 | + /* resolution out of hardware limit |
|---|
| 986 | + * frame is vertically divided into left and right |
|---|
| 987 | + */ |
|---|
| 988 | + isp->unite_index = ISP_UNITE_LEFT; |
|---|
| 989 | + if (hw->unite == ISP_UNITE_ONE) { |
|---|
| 990 | + isp->sw_rd_cnt *= 2; |
|---|
| 991 | + isp->sw_rd_cnt += 1; |
|---|
| 992 | + } |
|---|
| 993 | + /* first frame handle twice for thunderboot |
|---|
| 994 | + * first output stats to AIQ and wait new params to run second |
|---|
| 995 | + */ |
|---|
| 996 | + if (isp->is_pre_on && t.frame_id == 0) { |
|---|
| 997 | + isp->is_first_double = true; |
|---|
| 998 | + isp->skip_frame = 1; |
|---|
| 999 | + if (hw->unite != ISP_UNITE_ONE) { |
|---|
| 1000 | + isp->sw_rd_cnt = 0; |
|---|
| 1001 | + isp->is_frame_double = false; |
|---|
| 1002 | + } |
|---|
| 1003 | + rkisp_fast_switch_rx_buf(isp, false); |
|---|
| 1004 | + } |
|---|
| 1005 | + isp->params_vdev.rdbk_times = isp->sw_rd_cnt + 1; |
|---|
| 687 | 1006 | } |
|---|
| 688 | 1007 | end: |
|---|
| 689 | 1008 | spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags); |
|---|
| 690 | 1009 | if (times >= 0) |
|---|
| 691 | | - rkisp_trigger_read_back(isp, times, mode, false); |
|---|
| 1010 | + rkisp_trigger_read_back(isp, times, mode, is_try); |
|---|
| 692 | 1011 | } |
|---|
| 693 | 1012 | |
|---|
| 694 | 1013 | int rkisp_rdbk_trigger_event(struct rkisp_device *dev, u32 cmd, void *arg) |
|---|
| .. | .. |
|---|
| 697 | 1016 | struct isp2x_csi_trigger *trigger = NULL; |
|---|
| 698 | 1017 | unsigned long lock_flags = 0; |
|---|
| 699 | 1018 | int val, ret = 0; |
|---|
| 700 | | - |
|---|
| 701 | | - if (dev->dmarx_dev.trigger != T_MANUAL) |
|---|
| 702 | | - return 0; |
|---|
| 703 | 1019 | |
|---|
| 704 | 1020 | spin_lock_irqsave(&dev->rdbk_lock, lock_flags); |
|---|
| 705 | 1021 | switch (cmd) { |
|---|
| .. | .. |
|---|
| 732 | 1048 | return ret; |
|---|
| 733 | 1049 | } |
|---|
| 734 | 1050 | |
|---|
| 1051 | +static void rkisp_rdbk_work(struct work_struct *work) |
|---|
| 1052 | +{ |
|---|
| 1053 | + struct rkisp_device *dev = container_of(work, struct rkisp_device, rdbk_work); |
|---|
| 1054 | + |
|---|
| 1055 | + rkisp_dvfs(dev); |
|---|
| 1056 | + rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL); |
|---|
| 1057 | +} |
|---|
| 1058 | + |
|---|
| 735 | 1059 | void rkisp_check_idle(struct rkisp_device *dev, u32 irq) |
|---|
| 736 | 1060 | { |
|---|
| 737 | 1061 | u32 val = 0; |
|---|
| .. | .. |
|---|
| 750 | 1074 | !IS_HDR_RDBK(dev->rd_mode)) |
|---|
| 751 | 1075 | return; |
|---|
| 752 | 1076 | |
|---|
| 1077 | + if (dev->sw_rd_cnt) |
|---|
| 1078 | + goto end; |
|---|
| 1079 | + |
|---|
| 1080 | + if (dev->is_first_double) { |
|---|
| 1081 | + rkisp_fast_switch_rx_buf(dev, true); |
|---|
| 1082 | + dev->skip_frame = 0; |
|---|
| 1083 | + dev->irq_ends = 0; |
|---|
| 1084 | + return; |
|---|
| 1085 | + } |
|---|
| 1086 | + |
|---|
| 753 | 1087 | /* check output stream is off */ |
|---|
| 754 | | - val = ISP_FRAME_MP | ISP_FRAME_SP | ISP_FRAME_MPFBC; |
|---|
| 1088 | + val = ISP_FRAME_MP | ISP_FRAME_SP | ISP_FRAME_MPFBC | ISP_FRAME_BP; |
|---|
| 755 | 1089 | if (!(dev->irq_ends_mask & val)) { |
|---|
| 756 | 1090 | u32 state = dev->isp_state; |
|---|
| 757 | 1091 | struct rkisp_stream *s; |
|---|
| 758 | 1092 | |
|---|
| 759 | | - for (val = 0; val <= RKISP_STREAM_SP; val++) { |
|---|
| 1093 | + for (val = 0; val < RKISP_STREAM_VIR; val++) { |
|---|
| 760 | 1094 | s = &dev->cap_dev.stream[val]; |
|---|
| 761 | 1095 | dev->isp_state = ISP_STOP; |
|---|
| 762 | 1096 | if (s->streaming) { |
|---|
| .. | .. |
|---|
| 767 | 1101 | } |
|---|
| 768 | 1102 | |
|---|
| 769 | 1103 | val = 0; |
|---|
| 770 | | - dev->irq_ends = 0; |
|---|
| 771 | 1104 | switch (dev->rd_mode) { |
|---|
| 772 | 1105 | case HDR_RDBK_FRAME3://for rd1 rd0 rd2 |
|---|
| 773 | 1106 | val |= RAW1_RD_FRAME; |
|---|
| .. | .. |
|---|
| 780 | 1113 | /* FALLTHROUGH */ |
|---|
| 781 | 1114 | } |
|---|
| 782 | 1115 | rkisp2_rawrd_isr(val, dev); |
|---|
| 783 | | - if (dev->dmarx_dev.trigger == T_MANUAL) |
|---|
| 1116 | + |
|---|
| 1117 | +end: |
|---|
| 1118 | + dev->irq_ends = 0; |
|---|
| 1119 | + if (dev->hw_dev->is_dvfs) |
|---|
| 1120 | + schedule_work(&dev->rdbk_work); |
|---|
| 1121 | + else |
|---|
| 784 | 1122 | rkisp_rdbk_trigger_event(dev, T_CMD_END, NULL); |
|---|
| 785 | 1123 | if (dev->isp_state == ISP_STOP) |
|---|
| 786 | 1124 | wake_up(&dev->sync_onoff); |
|---|
| .. | .. |
|---|
| 803 | 1141 | */ |
|---|
| 804 | 1142 | static void rkisp_config_ism(struct rkisp_device *dev) |
|---|
| 805 | 1143 | { |
|---|
| 806 | | - void __iomem *base = dev->base_addr; |
|---|
| 807 | 1144 | struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop; |
|---|
| 808 | | - u32 val; |
|---|
| 1145 | + u32 width = out_crop->width, mult = 1; |
|---|
| 1146 | + u32 unite = dev->hw_dev->unite; |
|---|
| 809 | 1147 | |
|---|
| 810 | 1148 | /* isp2.0 no ism */ |
|---|
| 811 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1149 | + if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21 || |
|---|
| 1150 | + dev->isp_ver == ISP_V32_L) |
|---|
| 812 | 1151 | return; |
|---|
| 813 | 1152 | |
|---|
| 814 | | - writel(0, base + CIF_ISP_IS_RECENTER); |
|---|
| 815 | | - writel(0, base + CIF_ISP_IS_MAX_DX); |
|---|
| 816 | | - writel(0, base + CIF_ISP_IS_MAX_DY); |
|---|
| 817 | | - writel(0, base + CIF_ISP_IS_DISPLACE); |
|---|
| 818 | | - writel(out_crop->left, base + CIF_ISP_IS_H_OFFS); |
|---|
| 819 | | - writel(out_crop->top, base + CIF_ISP_IS_V_OFFS); |
|---|
| 820 | | - writel(out_crop->width, base + CIF_ISP_IS_H_SIZE); |
|---|
| 1153 | + if (unite) |
|---|
| 1154 | + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1155 | + rkisp_unite_write(dev, CIF_ISP_IS_RECENTER, 0, false); |
|---|
| 1156 | + rkisp_unite_write(dev, CIF_ISP_IS_MAX_DX, 0, false); |
|---|
| 1157 | + rkisp_unite_write(dev, CIF_ISP_IS_MAX_DY, 0, false); |
|---|
| 1158 | + rkisp_unite_write(dev, CIF_ISP_IS_DISPLACE, 0, false); |
|---|
| 1159 | + rkisp_unite_write(dev, CIF_ISP_IS_H_OFFS, out_crop->left, false); |
|---|
| 1160 | + rkisp_unite_write(dev, CIF_ISP_IS_V_OFFS, out_crop->top, false); |
|---|
| 1161 | + rkisp_unite_write(dev, CIF_ISP_IS_H_SIZE, width, false); |
|---|
| 821 | 1162 | if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) |
|---|
| 822 | | - writel(out_crop->height / 2, base + CIF_ISP_IS_V_SIZE); |
|---|
| 823 | | - else |
|---|
| 824 | | - writel(out_crop->height, base + CIF_ISP_IS_V_SIZE); |
|---|
| 1163 | + mult = 2; |
|---|
| 1164 | + rkisp_unite_write(dev, CIF_ISP_IS_V_SIZE, out_crop->height / mult, false); |
|---|
| 1165 | + |
|---|
| 1166 | + if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) |
|---|
| 1167 | + return; |
|---|
| 825 | 1168 | |
|---|
| 826 | 1169 | /* IS(Image Stabilization) is always on, working as output crop */ |
|---|
| 827 | | - writel(1, base + CIF_ISP_IS_CTRL); |
|---|
| 828 | | - val = readl(base + CIF_ISP_CTRL); |
|---|
| 829 | | - val |= CIF_ISP_CTRL_ISP_CFG_UPD; |
|---|
| 830 | | - writel(val, base + CIF_ISP_CTRL); |
|---|
| 1170 | + rkisp_write(dev, CIF_ISP_IS_CTRL, 1, false); |
|---|
| 831 | 1171 | } |
|---|
| 832 | 1172 | |
|---|
| 833 | 1173 | static int rkisp_reset_handle_v2x(struct rkisp_device *dev) |
|---|
| .. | .. |
|---|
| 984 | 1324 | !(monitor->state & ISP_MIPI_ERROR))) { |
|---|
| 985 | 1325 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 986 | 1326 | isp = hw->isp[i]; |
|---|
| 987 | | - if (!(isp->isp_inp & INP_CSI)) |
|---|
| 1327 | + if (!isp || (isp && !(isp->isp_inp & INP_CSI))) |
|---|
| 988 | 1328 | continue; |
|---|
| 989 | 1329 | if (!(isp->isp_state & ISP_START)) |
|---|
| 990 | 1330 | break; |
|---|
| .. | .. |
|---|
| 1006 | 1346 | } |
|---|
| 1007 | 1347 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 1008 | 1348 | isp = hw->isp[i]; |
|---|
| 1349 | + if (!isp) |
|---|
| 1350 | + continue; |
|---|
| 1009 | 1351 | if (isp->isp_inp & INP_CSI || |
|---|
| 1010 | 1352 | isp->isp_inp & INP_DVP || |
|---|
| 1011 | 1353 | isp->isp_inp & INP_LVDS) { |
|---|
| .. | .. |
|---|
| 1032 | 1374 | |
|---|
| 1033 | 1375 | for (i = 0; i < hw->dev_num; i++) { |
|---|
| 1034 | 1376 | isp = hw->isp[i]; |
|---|
| 1377 | + if (!isp) |
|---|
| 1378 | + continue; |
|---|
| 1035 | 1379 | if (isp->isp_inp & INP_CSI || |
|---|
| 1036 | 1380 | isp->isp_inp & INP_DVP || |
|---|
| 1037 | 1381 | isp->isp_inp & INP_LVDS) { |
|---|
| .. | .. |
|---|
| 1085 | 1429 | */ |
|---|
| 1086 | 1430 | static void rkisp_config_color_space(struct rkisp_device *dev) |
|---|
| 1087 | 1431 | { |
|---|
| 1432 | + u32 val = 0; |
|---|
| 1433 | + |
|---|
| 1088 | 1434 | u16 bt601_coeff[] = { |
|---|
| 1089 | 1435 | 0x0026, 0x004b, 0x000f, |
|---|
| 1090 | 1436 | 0x01ea, 0x01d6, 0x0040, |
|---|
| .. | .. |
|---|
| 1116 | 1462 | } |
|---|
| 1117 | 1463 | |
|---|
| 1118 | 1464 | for (i = 0; i < 9; i++) |
|---|
| 1119 | | - rkisp_write(dev, CIF_ISP_CC_COEFF_0 + i * 4, *(coeff + i), false); |
|---|
| 1465 | + rkisp_unite_write(dev, CIF_ISP_CC_COEFF_0 + i * 4, |
|---|
| 1466 | + *(coeff + i), false); |
|---|
| 1467 | + |
|---|
| 1468 | + val = rkisp_read_reg_cache(dev, CIF_ISP_CTRL); |
|---|
| 1120 | 1469 | |
|---|
| 1121 | 1470 | if (dev->isp_sdev.quantization == V4L2_QUANTIZATION_FULL_RANGE) |
|---|
| 1122 | | - rkisp_set_bits(dev, CIF_ISP_CTRL, 0, |
|---|
| 1123 | | - CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1124 | | - CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false); |
|---|
| 1471 | + rkisp_unite_write(dev, CIF_ISP_CTRL, val | |
|---|
| 1472 | + CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1473 | + CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false); |
|---|
| 1125 | 1474 | else |
|---|
| 1126 | | - rkisp_clear_bits(dev, CIF_ISP_CTRL, |
|---|
| 1127 | | - CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1128 | | - CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA, false); |
|---|
| 1475 | + rkisp_unite_write(dev, CIF_ISP_CTRL, val & |
|---|
| 1476 | + ~(CIF_ISP_CTRL_ISP_CSM_Y_FULL_ENA | |
|---|
| 1477 | + CIF_ISP_CTRL_ISP_CSM_C_FULL_ENA), false); |
|---|
| 1478 | +} |
|---|
| 1479 | + |
|---|
| 1480 | +static void rkisp_config_cmsk_single(struct rkisp_device *dev, |
|---|
| 1481 | + struct rkisp_cmsk_cfg *cfg) |
|---|
| 1482 | +{ |
|---|
| 1483 | + u32 i, val, ctrl = 0; |
|---|
| 1484 | + u32 mp_en = cfg->win[0].win_en; |
|---|
| 1485 | + u32 sp_en = cfg->win[1].win_en; |
|---|
| 1486 | + u32 bp_en = cfg->win[2].win_en; |
|---|
| 1487 | + u32 win_max = (dev->isp_ver == ISP_V30) ? |
|---|
| 1488 | + RKISP_CMSK_WIN_MAX_V30 : RKISP_CMSK_WIN_MAX; |
|---|
| 1489 | + |
|---|
| 1490 | + if (mp_en) { |
|---|
| 1491 | + ctrl |= ISP3X_SW_CMSK_EN_MP; |
|---|
| 1492 | + rkisp_write(dev, ISP3X_CMSK_CTRL1, mp_en, false); |
|---|
| 1493 | + val = cfg->win[0].mode; |
|---|
| 1494 | + rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false); |
|---|
| 1495 | + } |
|---|
| 1496 | + |
|---|
| 1497 | + if (sp_en) { |
|---|
| 1498 | + ctrl |= ISP3X_SW_CMSK_EN_SP; |
|---|
| 1499 | + rkisp_write(dev, ISP3X_CMSK_CTRL2, sp_en, false); |
|---|
| 1500 | + val = cfg->win[1].mode; |
|---|
| 1501 | + rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false); |
|---|
| 1502 | + } |
|---|
| 1503 | + |
|---|
| 1504 | + if (bp_en) { |
|---|
| 1505 | + ctrl |= ISP3X_SW_CMSK_EN_BP; |
|---|
| 1506 | + rkisp_write(dev, ISP3X_CMSK_CTRL3, bp_en, false); |
|---|
| 1507 | + val = cfg->win[2].mode; |
|---|
| 1508 | + rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false); |
|---|
| 1509 | + } |
|---|
| 1510 | + |
|---|
| 1511 | + for (i = 0; i < win_max; i++) { |
|---|
| 1512 | + if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i))) |
|---|
| 1513 | + continue; |
|---|
| 1514 | + |
|---|
| 1515 | + val = ISP3X_SW_CMSK_YUV(cfg->win[i].cover_color_y, |
|---|
| 1516 | + cfg->win[i].cover_color_u, |
|---|
| 1517 | + cfg->win[i].cover_color_v); |
|---|
| 1518 | + rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); |
|---|
| 1519 | + |
|---|
| 1520 | + val = ISP_PACK_2SHORT(cfg->win[i].h_offs, cfg->win[i].v_offs); |
|---|
| 1521 | + rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); |
|---|
| 1522 | + |
|---|
| 1523 | + val = ISP_PACK_2SHORT(cfg->win[i].h_size, cfg->win[i].v_size); |
|---|
| 1524 | + rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); |
|---|
| 1525 | + } |
|---|
| 1526 | + |
|---|
| 1527 | + if (ctrl) { |
|---|
| 1528 | + val = ISP_PACK_2SHORT(dev->isp_sdev.out_crop.width, |
|---|
| 1529 | + dev->isp_sdev.out_crop.height); |
|---|
| 1530 | + rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); |
|---|
| 1531 | + ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; |
|---|
| 1532 | + ctrl |= ISP3X_SW_CMSK_BLKSIZE(cfg->mosaic_block); |
|---|
| 1533 | + } |
|---|
| 1534 | + rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); |
|---|
| 1535 | + |
|---|
| 1536 | + val = rkisp_read(dev, ISP3X_CMSK_CTRL0, true); |
|---|
| 1537 | + if (dev->hw_dev->is_single && |
|---|
| 1538 | + ((val & ISP32_SW_CMSK_EN_PATH) != (val & ISP32_SW_CMSK_EN_PATH_SHD))) |
|---|
| 1539 | + rkisp_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, true); |
|---|
| 1540 | +} |
|---|
| 1541 | + |
|---|
| 1542 | +static void rkisp_config_cmsk_dual(struct rkisp_device *dev, |
|---|
| 1543 | + struct rkisp_cmsk_cfg *cfg) |
|---|
| 1544 | +{ |
|---|
| 1545 | + struct rkisp_cmsk_cfg left = *cfg; |
|---|
| 1546 | + struct rkisp_cmsk_cfg right = *cfg; |
|---|
| 1547 | + u32 width = dev->isp_sdev.out_crop.width; |
|---|
| 1548 | + u32 height = dev->isp_sdev.out_crop.height; |
|---|
| 1549 | + u32 w = width / 2; |
|---|
| 1550 | + u32 i, val, h_offs, h_size, ctrl; |
|---|
| 1551 | + u8 mp_en = cfg->win[0].win_en; |
|---|
| 1552 | + u8 sp_en = cfg->win[1].win_en; |
|---|
| 1553 | + u8 bp_en = cfg->win[2].win_en; |
|---|
| 1554 | + u32 win_max = (dev->isp_ver == ISP_V30) ? |
|---|
| 1555 | + RKISP_CMSK_WIN_MAX_V30 : RKISP_CMSK_WIN_MAX; |
|---|
| 1556 | + |
|---|
| 1557 | + for (i = 0; i < win_max; i++) { |
|---|
| 1558 | + if (!(mp_en & BIT(i)) && !(sp_en & BIT(i)) && !(bp_en & BIT(i))) |
|---|
| 1559 | + continue; |
|---|
| 1560 | + |
|---|
| 1561 | + h_offs = cfg->win[i].h_offs; |
|---|
| 1562 | + h_size = cfg->win[i].h_size; |
|---|
| 1563 | + if (h_offs + h_size <= w) { |
|---|
| 1564 | + /* cmsk window at left isp */ |
|---|
| 1565 | + right.win[0].win_en &= ~BIT(i); |
|---|
| 1566 | + right.win[1].win_en &= ~BIT(i); |
|---|
| 1567 | + right.win[2].win_en &= ~BIT(i); |
|---|
| 1568 | + } else if (h_offs >= w) { |
|---|
| 1569 | + /* cmsk window at right isp */ |
|---|
| 1570 | + left.win[0].win_en &= ~BIT(i); |
|---|
| 1571 | + left.win[1].win_en &= ~BIT(i); |
|---|
| 1572 | + left.win[2].win_en &= ~BIT(i); |
|---|
| 1573 | + } else { |
|---|
| 1574 | + /* cmsk window at dual isp */ |
|---|
| 1575 | + left.win[i].h_size = ALIGN(w - h_offs, 8); |
|---|
| 1576 | + |
|---|
| 1577 | + right.win[i].h_offs = RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1578 | + val = h_offs + h_size - w; |
|---|
| 1579 | + right.win[i].h_size = ALIGN(val, 8); |
|---|
| 1580 | + right.win[i].h_offs -= right.win[i].h_size - val; |
|---|
| 1581 | + } |
|---|
| 1582 | + |
|---|
| 1583 | + val = ISP3X_SW_CMSK_YUV(left.win[i].cover_color_y, |
|---|
| 1584 | + left.win[i].cover_color_u, |
|---|
| 1585 | + left.win[i].cover_color_v); |
|---|
| 1586 | + rkisp_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); |
|---|
| 1587 | + rkisp_next_write(dev, ISP3X_CMSK_YUV0 + i * 4, val, false); |
|---|
| 1588 | + |
|---|
| 1589 | + val = ISP_PACK_2SHORT(left.win[i].h_offs, left.win[i].v_offs); |
|---|
| 1590 | + rkisp_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); |
|---|
| 1591 | + val = ISP_PACK_2SHORT(left.win[i].h_size, left.win[i].v_size); |
|---|
| 1592 | + rkisp_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); |
|---|
| 1593 | + |
|---|
| 1594 | + val = ISP_PACK_2SHORT(right.win[i].h_offs, right.win[i].v_offs); |
|---|
| 1595 | + rkisp_next_write(dev, ISP3X_CMSK_OFFS0 + i * 8, val, false); |
|---|
| 1596 | + val = ISP_PACK_2SHORT(right.win[i].h_size, right.win[i].v_size); |
|---|
| 1597 | + rkisp_next_write(dev, ISP3X_CMSK_SIZE0 + i * 8, val, false); |
|---|
| 1598 | + } |
|---|
| 1599 | + |
|---|
| 1600 | + w += RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1601 | + ctrl = 0; |
|---|
| 1602 | + if (left.win[0].win_en) { |
|---|
| 1603 | + ctrl |= ISP3X_SW_CMSK_EN_MP; |
|---|
| 1604 | + rkisp_write(dev, ISP3X_CMSK_CTRL1, left.win[0].win_en, false); |
|---|
| 1605 | + val = left.win[0].mode; |
|---|
| 1606 | + rkisp_write(dev, ISP3X_CMSK_CTRL4, val, false); |
|---|
| 1607 | + } |
|---|
| 1608 | + if (left.win[1].win_en) { |
|---|
| 1609 | + ctrl |= ISP3X_SW_CMSK_EN_SP; |
|---|
| 1610 | + rkisp_write(dev, ISP3X_CMSK_CTRL2, left.win[1].win_en, false); |
|---|
| 1611 | + val = left.win[1].mode; |
|---|
| 1612 | + rkisp_write(dev, ISP3X_CMSK_CTRL5, val, false); |
|---|
| 1613 | + } |
|---|
| 1614 | + if (left.win[2].win_en) { |
|---|
| 1615 | + ctrl |= ISP3X_SW_CMSK_EN_BP; |
|---|
| 1616 | + rkisp_write(dev, ISP3X_CMSK_CTRL3, left.win[2].win_en, false); |
|---|
| 1617 | + val = left.win[2].mode; |
|---|
| 1618 | + rkisp_write(dev, ISP3X_CMSK_CTRL6, val, false); |
|---|
| 1619 | + } |
|---|
| 1620 | + if (ctrl) { |
|---|
| 1621 | + val = ISP_PACK_2SHORT(w, height); |
|---|
| 1622 | + rkisp_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); |
|---|
| 1623 | + ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; |
|---|
| 1624 | + } |
|---|
| 1625 | + rkisp_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); |
|---|
| 1626 | + |
|---|
| 1627 | + ctrl = 0; |
|---|
| 1628 | + if (right.win[0].win_en) { |
|---|
| 1629 | + ctrl |= ISP3X_SW_CMSK_EN_MP; |
|---|
| 1630 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL1, right.win[0].win_en, false); |
|---|
| 1631 | + val = right.win[0].mode; |
|---|
| 1632 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL4, val, false); |
|---|
| 1633 | + } |
|---|
| 1634 | + if (right.win[1].win_en) { |
|---|
| 1635 | + ctrl |= ISP3X_SW_CMSK_EN_SP; |
|---|
| 1636 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL2, right.win[1].win_en, false); |
|---|
| 1637 | + val = right.win[1].mode; |
|---|
| 1638 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL5, val, false); |
|---|
| 1639 | + } |
|---|
| 1640 | + if (right.win[2].win_en) { |
|---|
| 1641 | + ctrl |= ISP3X_SW_CMSK_EN_BP; |
|---|
| 1642 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL3, right.win[2].win_en, false); |
|---|
| 1643 | + val = right.win[2].mode; |
|---|
| 1644 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL6, val, false); |
|---|
| 1645 | + } |
|---|
| 1646 | + if (ctrl) { |
|---|
| 1647 | + val = ISP_PACK_2SHORT(w, height); |
|---|
| 1648 | + rkisp_next_write(dev, ISP3X_CMSK_PIC_SIZE, val, false); |
|---|
| 1649 | + ctrl |= ISP3X_SW_CMSK_EN | ISP3X_SW_CMSK_ORDER_MODE; |
|---|
| 1650 | + } |
|---|
| 1651 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL0, ctrl, false); |
|---|
| 1652 | + |
|---|
| 1653 | + val = rkisp_next_read(dev, ISP3X_CMSK_CTRL0, true); |
|---|
| 1654 | + if (dev->hw_dev->is_single && |
|---|
| 1655 | + ((val & ISP32_SW_CMSK_EN_PATH) != (val & ISP32_SW_CMSK_EN_PATH_SHD))) |
|---|
| 1656 | + rkisp_next_write(dev, ISP3X_CMSK_CTRL0, val | ISP3X_SW_CMSK_FORCE_UPD, false); |
|---|
| 1657 | +} |
|---|
| 1658 | + |
|---|
| 1659 | +static void rkisp_config_cmsk(struct rkisp_device *dev) |
|---|
| 1660 | +{ |
|---|
| 1661 | + unsigned long lock_flags = 0; |
|---|
| 1662 | + struct rkisp_cmsk_cfg cfg; |
|---|
| 1663 | + |
|---|
| 1664 | + if (dev->isp_ver != ISP_V30 && dev->isp_ver != ISP_V32) |
|---|
| 1665 | + return; |
|---|
| 1666 | + |
|---|
| 1667 | + spin_lock_irqsave(&dev->cmsk_lock, lock_flags); |
|---|
| 1668 | + if (!dev->is_cmsk_upd) { |
|---|
| 1669 | + spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags); |
|---|
| 1670 | + return; |
|---|
| 1671 | + } |
|---|
| 1672 | + dev->is_cmsk_upd = false; |
|---|
| 1673 | + cfg = dev->cmsk_cfg; |
|---|
| 1674 | + spin_unlock_irqrestore(&dev->cmsk_lock, lock_flags); |
|---|
| 1675 | + |
|---|
| 1676 | + if (!dev->hw_dev->unite) |
|---|
| 1677 | + rkisp_config_cmsk_single(dev, &cfg); |
|---|
| 1678 | + else |
|---|
| 1679 | + rkisp_config_cmsk_dual(dev, &cfg); |
|---|
| 1129 | 1680 | } |
|---|
| 1130 | 1681 | |
|---|
| 1131 | 1682 | /* |
|---|
| .. | .. |
|---|
| 1137 | 1688 | struct ispsd_out_fmt *out_fmt; |
|---|
| 1138 | 1689 | struct v4l2_rect *in_crop; |
|---|
| 1139 | 1690 | struct rkisp_sensor_info *sensor; |
|---|
| 1691 | + bool is_unite = !!dev->hw_dev->unite; |
|---|
| 1140 | 1692 | u32 isp_ctrl = 0; |
|---|
| 1141 | 1693 | u32 irq_mask = 0; |
|---|
| 1142 | 1694 | u32 signal = 0; |
|---|
| 1143 | 1695 | u32 acq_mult = 0; |
|---|
| 1144 | 1696 | u32 acq_prop = 0; |
|---|
| 1145 | 1697 | u32 extend_line = 0; |
|---|
| 1698 | + u32 width; |
|---|
| 1146 | 1699 | |
|---|
| 1147 | 1700 | sensor = dev->active_sensor; |
|---|
| 1148 | 1701 | in_fmt = &dev->isp_sdev.in_fmt; |
|---|
| 1149 | 1702 | out_fmt = &dev->isp_sdev.out_fmt; |
|---|
| 1150 | 1703 | in_crop = &dev->isp_sdev.in_crop; |
|---|
| 1704 | + width = in_crop->width; |
|---|
| 1151 | 1705 | |
|---|
| 1152 | 1706 | if (in_fmt->fmt_type == FMT_BAYER) { |
|---|
| 1153 | 1707 | acq_mult = 1; |
|---|
| .. | .. |
|---|
| 1163 | 1717 | if (in_fmt->mbus_code == MEDIA_BUS_FMT_Y8_1X8 || |
|---|
| 1164 | 1718 | in_fmt->mbus_code == MEDIA_BUS_FMT_Y10_1X10 || |
|---|
| 1165 | 1719 | in_fmt->mbus_code == MEDIA_BUS_FMT_Y12_1X12) { |
|---|
| 1166 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1167 | | - rkisp_write(dev, ISP_DEBAYER_CONTROL, 0, false); |
|---|
| 1720 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1721 | + rkisp_unite_write(dev, ISP_DEBAYER_CONTROL, 0, false); |
|---|
| 1168 | 1722 | else |
|---|
| 1169 | 1723 | rkisp_write(dev, CIF_ISP_DEMOSAIC, |
|---|
| 1170 | | - CIF_ISP_DEMOSAIC_BYPASS | |
|---|
| 1171 | | - CIF_ISP_DEMOSAIC_TH(0xc), false); |
|---|
| 1724 | + CIF_ISP_DEMOSAIC_BYPASS | |
|---|
| 1725 | + CIF_ISP_DEMOSAIC_TH(0xc), false); |
|---|
| 1172 | 1726 | } else { |
|---|
| 1173 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1174 | | - rkisp_write(dev, ISP_DEBAYER_CONTROL, |
|---|
| 1175 | | - SW_DEBAYER_EN | |
|---|
| 1176 | | - SW_DEBAYER_FILTER_G_EN | |
|---|
| 1177 | | - SW_DEBAYER_FILTER_C_EN, false); |
|---|
| 1727 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1728 | + rkisp_unite_write(dev, ISP_DEBAYER_CONTROL, |
|---|
| 1729 | + SW_DEBAYER_EN | |
|---|
| 1730 | + SW_DEBAYER_FILTER_G_EN | |
|---|
| 1731 | + SW_DEBAYER_FILTER_C_EN, false); |
|---|
| 1178 | 1732 | else |
|---|
| 1179 | 1733 | rkisp_write(dev, CIF_ISP_DEMOSAIC, |
|---|
| 1180 | | - CIF_ISP_DEMOSAIC_TH(0xc), false); |
|---|
| 1734 | + CIF_ISP_DEMOSAIC_TH(0xc), false); |
|---|
| 1181 | 1735 | } |
|---|
| 1182 | 1736 | |
|---|
| 1183 | 1737 | if (sensor && sensor->mbus.type == V4L2_MBUS_BT656) |
|---|
| .. | .. |
|---|
| 1195 | 1749 | } else if (in_fmt->fmt_type == FMT_YUV) { |
|---|
| 1196 | 1750 | acq_mult = 2; |
|---|
| 1197 | 1751 | if (sensor && |
|---|
| 1198 | | - (sensor->mbus.type == V4L2_MBUS_CSI2 || |
|---|
| 1752 | + (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY || |
|---|
| 1199 | 1753 | sensor->mbus.type == V4L2_MBUS_CCP2)) { |
|---|
| 1200 | 1754 | isp_ctrl = CIF_ISP_CTRL_ISP_MODE_ITU601; |
|---|
| 1201 | 1755 | } else { |
|---|
| .. | .. |
|---|
| 1227 | 1781 | signal |= CIF_ISP_ACQ_PROP_HSYNC_LOW; |
|---|
| 1228 | 1782 | } |
|---|
| 1229 | 1783 | |
|---|
| 1230 | | - rkisp_write(dev, CIF_ISP_CTRL, isp_ctrl, false); |
|---|
| 1784 | + if (rkisp_read_reg_cache(dev, CIF_ISP_CTRL) & ISP32_MIR_ENABLE) |
|---|
| 1785 | + isp_ctrl |= ISP32_MIR_ENABLE; |
|---|
| 1786 | + |
|---|
| 1787 | + rkisp_unite_write(dev, CIF_ISP_CTRL, isp_ctrl, false); |
|---|
| 1231 | 1788 | acq_prop |= signal | in_fmt->yuv_seq | |
|---|
| 1232 | 1789 | CIF_ISP_ACQ_PROP_BAYER_PAT(in_fmt->bayer_pat) | |
|---|
| 1233 | 1790 | CIF_ISP_ACQ_PROP_FIELD_SEL_ALL; |
|---|
| 1234 | | - rkisp_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false); |
|---|
| 1235 | | - rkisp_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true); |
|---|
| 1791 | + rkisp_unite_write(dev, CIF_ISP_ACQ_PROP, acq_prop, false); |
|---|
| 1792 | + rkisp_unite_write(dev, CIF_ISP_ACQ_NR_FRAMES, 0, true); |
|---|
| 1236 | 1793 | |
|---|
| 1794 | + if (is_unite) |
|---|
| 1795 | + width = width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 1237 | 1796 | /* Acquisition Size */ |
|---|
| 1238 | | - rkisp_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false); |
|---|
| 1239 | | - rkisp_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false); |
|---|
| 1240 | | - rkisp_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * in_crop->width, false); |
|---|
| 1797 | + rkisp_unite_write(dev, CIF_ISP_ACQ_H_OFFS, acq_mult * in_crop->left, false); |
|---|
| 1798 | + rkisp_unite_write(dev, CIF_ISP_ACQ_V_OFFS, in_crop->top, false); |
|---|
| 1799 | + rkisp_unite_write(dev, CIF_ISP_ACQ_H_SIZE, acq_mult * width, false); |
|---|
| 1241 | 1800 | |
|---|
| 1242 | 1801 | /* ISP Out Area differ with ACQ is only FIFO, so don't crop in this */ |
|---|
| 1243 | | - rkisp_write(dev, CIF_ISP_OUT_H_OFFS, 0, true); |
|---|
| 1244 | | - rkisp_write(dev, CIF_ISP_OUT_V_OFFS, 0, true); |
|---|
| 1245 | | - rkisp_write(dev, CIF_ISP_OUT_H_SIZE, in_crop->width, false); |
|---|
| 1802 | + rkisp_unite_write(dev, CIF_ISP_OUT_H_OFFS, 0, true); |
|---|
| 1803 | + rkisp_unite_write(dev, CIF_ISP_OUT_V_OFFS, 0, true); |
|---|
| 1804 | + rkisp_unite_write(dev, CIF_ISP_OUT_H_SIZE, width, false); |
|---|
| 1246 | 1805 | |
|---|
| 1247 | 1806 | if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { |
|---|
| 1248 | | - rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false); |
|---|
| 1249 | | - rkisp_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false); |
|---|
| 1807 | + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height / 2, false); |
|---|
| 1808 | + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height / 2, false); |
|---|
| 1250 | 1809 | } else { |
|---|
| 1251 | | - rkisp_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false); |
|---|
| 1252 | | - rkisp_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false); |
|---|
| 1810 | + rkisp_unite_write(dev, CIF_ISP_ACQ_V_SIZE, in_crop->height + extend_line, false); |
|---|
| 1811 | + rkisp_unite_write(dev, CIF_ISP_OUT_V_SIZE, in_crop->height + extend_line, false); |
|---|
| 1253 | 1812 | } |
|---|
| 1254 | 1813 | |
|---|
| 1255 | 1814 | /* interrupt mask */ |
|---|
| 1256 | | - irq_mask |= CIF_ISP_FRAME | CIF_ISP_V_START | CIF_ISP_PIC_SIZE_ERROR | |
|---|
| 1257 | | - CIF_ISP_FRAME_IN; |
|---|
| 1258 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 1815 | + irq_mask |= CIF_ISP_FRAME | CIF_ISP_V_START | CIF_ISP_PIC_SIZE_ERROR; |
|---|
| 1816 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1259 | 1817 | irq_mask |= ISP2X_LSC_LUT_ERR; |
|---|
| 1260 | | - rkisp_write(dev, CIF_ISP_IMSC, irq_mask, true); |
|---|
| 1818 | + if (dev->is_pre_on) |
|---|
| 1819 | + irq_mask |= CIF_ISP_FRAME_IN; |
|---|
| 1820 | + rkisp_unite_write(dev, CIF_ISP_IMSC, irq_mask, true); |
|---|
| 1261 | 1821 | |
|---|
| 1262 | | - if ((dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) && |
|---|
| 1822 | + if ((dev->isp_ver == ISP_V20 || |
|---|
| 1823 | + dev->isp_ver == ISP_V21) && |
|---|
| 1263 | 1824 | IS_HDR_RDBK(dev->hdr.op_mode)) { |
|---|
| 1264 | 1825 | irq_mask = ISP2X_3A_RAWAE_BIG; |
|---|
| 1265 | 1826 | rkisp_write(dev, ISP_ISP3A_IMSC, irq_mask, true); |
|---|
| .. | .. |
|---|
| 1276 | 1837 | rkisp_update_regs(dev, CIF_ISP_ACQ_H_OFFS, CIF_ISP_ACQ_V_SIZE); |
|---|
| 1277 | 1838 | rkisp_update_regs(dev, CIF_ISP_OUT_H_SIZE, CIF_ISP_OUT_V_SIZE); |
|---|
| 1278 | 1839 | } |
|---|
| 1840 | + |
|---|
| 1841 | + rkisp_config_cmsk(dev); |
|---|
| 1279 | 1842 | return 0; |
|---|
| 1280 | 1843 | } |
|---|
| 1281 | 1844 | |
|---|
| .. | .. |
|---|
| 1379 | 1942 | /* Configure MUX */ |
|---|
| 1380 | 1943 | static int rkisp_config_path(struct rkisp_device *dev) |
|---|
| 1381 | 1944 | { |
|---|
| 1382 | | - int ret = 0; |
|---|
| 1383 | 1945 | struct rkisp_sensor_info *sensor = dev->active_sensor; |
|---|
| 1384 | | - u32 dpcl = readl(dev->base_addr + CIF_VI_DPCL); |
|---|
| 1946 | + int ret = 0; |
|---|
| 1947 | + u32 dpcl = 0; |
|---|
| 1385 | 1948 | |
|---|
| 1386 | 1949 | /* isp input interface selects */ |
|---|
| 1387 | | - if ((sensor && sensor->mbus.type == V4L2_MBUS_CSI2) || |
|---|
| 1950 | + if ((sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) || |
|---|
| 1388 | 1951 | dev->isp_inp & (INP_RAWRD0 | INP_RAWRD1 | INP_RAWRD2 | INP_CIF)) { |
|---|
| 1389 | 1952 | /* mipi sensor->isp or isp read from ddr */ |
|---|
| 1390 | 1953 | dpcl |= CIF_VI_DPCL_IF_SEL_MIPI; |
|---|
| .. | .. |
|---|
| 1406 | 1969 | ret = -EINVAL; |
|---|
| 1407 | 1970 | } |
|---|
| 1408 | 1971 | |
|---|
| 1409 | | - /* fix 3a_wr no output with selfpath */ |
|---|
| 1410 | | - if (dev->isp_ver == ISP_V21) |
|---|
| 1411 | | - dpcl |= CIF_VI_DPCL_CHAN_MODE_MP | CIF_VI_DPCL_MP_MUX_MRSZ_MI; |
|---|
| 1972 | + if (dev->isp_ver == ISP_V32) |
|---|
| 1973 | + dpcl |= BIT(0); |
|---|
| 1412 | 1974 | |
|---|
| 1413 | | - writel(dpcl, dev->base_addr + CIF_VI_DPCL); |
|---|
| 1414 | | - |
|---|
| 1975 | + rkisp_unite_set_bits(dev, CIF_VI_DPCL, 0, dpcl, true); |
|---|
| 1415 | 1976 | return ret; |
|---|
| 1416 | 1977 | } |
|---|
| 1417 | 1978 | |
|---|
| .. | .. |
|---|
| 1483 | 2044 | int ret = 1000; |
|---|
| 1484 | 2045 | |
|---|
| 1485 | 2046 | if (!rkisp_is_need_3a(dev) || dev->isp_ver == ISP_V20 || |
|---|
| 1486 | | - !params_vdev->is_subs_evt) |
|---|
| 2047 | + !params_vdev->is_subs_evt || dev->hw_dev->is_shutdown) |
|---|
| 1487 | 2048 | return; |
|---|
| 1488 | 2049 | |
|---|
| 1489 | 2050 | v4l2_event_queue(vdev, &ev); |
|---|
| .. | .. |
|---|
| 1500 | 2061 | /* Mess register operations to stop isp */ |
|---|
| 1501 | 2062 | static int rkisp_isp_stop(struct rkisp_device *dev) |
|---|
| 1502 | 2063 | { |
|---|
| 2064 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 1503 | 2065 | void __iomem *base = dev->base_addr; |
|---|
| 1504 | 2066 | unsigned long old_rate, safe_rate; |
|---|
| 1505 | 2067 | u32 val; |
|---|
| .. | .. |
|---|
| 1507 | 2069 | |
|---|
| 1508 | 2070 | v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 1509 | 2071 | "%s refcnt:%d\n", __func__, |
|---|
| 1510 | | - atomic_read(&dev->hw_dev->refcnt)); |
|---|
| 2072 | + atomic_read(&hw->refcnt)); |
|---|
| 1511 | 2073 | |
|---|
| 1512 | | - if (atomic_read(&dev->hw_dev->refcnt) > 1) |
|---|
| 2074 | + if (atomic_read(&hw->refcnt) > 1) |
|---|
| 1513 | 2075 | goto end; |
|---|
| 1514 | 2076 | /* |
|---|
| 1515 | 2077 | * ISP(mi) stop in mi frame end -> Stop ISP(mipi) -> |
|---|
| .. | .. |
|---|
| 1523 | 2085 | readl(base + CIF_ISP_CSI0_ERR1); |
|---|
| 1524 | 2086 | readl(base + CIF_ISP_CSI0_ERR2); |
|---|
| 1525 | 2087 | readl(base + CIF_ISP_CSI0_ERR3); |
|---|
| 1526 | | - } else if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2088 | + } else if (dev->isp_ver >= ISP_V20) { |
|---|
| 1527 | 2089 | writel(0, base + CSI2RX_MASK_PHY); |
|---|
| 1528 | 2090 | writel(0, base + CSI2RX_MASK_PACKET); |
|---|
| 1529 | 2091 | writel(0, base + CSI2RX_MASK_OVERFLOW); |
|---|
| .. | .. |
|---|
| 1540 | 2102 | writel(0, base + CIF_ISP_IMSC); |
|---|
| 1541 | 2103 | writel(~0, base + CIF_ISP_ICR); |
|---|
| 1542 | 2104 | |
|---|
| 1543 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2105 | + if (dev->isp_ver >= ISP_V20) { |
|---|
| 1544 | 2106 | writel(0, base + ISP_ISP3A_IMSC); |
|---|
| 1545 | 2107 | writel(~0, base + ISP_ISP3A_ICR); |
|---|
| 1546 | 2108 | } |
|---|
| .. | .. |
|---|
| 1556 | 2118 | udelay(20); |
|---|
| 1557 | 2119 | } |
|---|
| 1558 | 2120 | /* stop lsc to avoid lsclut error */ |
|---|
| 1559 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 2121 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1560 | 2122 | writel(0, base + ISP_LSC_CTRL); |
|---|
| 1561 | 2123 | /* stop ISP */ |
|---|
| 1562 | 2124 | val = readl(base + CIF_ISP_CTRL); |
|---|
| .. | .. |
|---|
| 1565 | 2127 | |
|---|
| 1566 | 2128 | val = readl(base + CIF_ISP_CTRL); |
|---|
| 1567 | 2129 | writel(val | CIF_ISP_CTRL_ISP_CFG_UPD, base + CIF_ISP_CTRL); |
|---|
| 2130 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 2131 | + rkisp_next_write(dev, CIF_ISP_CTRL, |
|---|
| 2132 | + val | CIF_ISP_CTRL_ISP_CFG_UPD, true); |
|---|
| 1568 | 2133 | |
|---|
| 1569 | 2134 | readx_poll_timeout_atomic(readl, base + CIF_ISP_RIS, |
|---|
| 1570 | 2135 | val, val & CIF_ISP_OFF, 20, 100); |
|---|
| .. | .. |
|---|
| 1572 | 2137 | "MI_CTRL:%x, ISP_CTRL:%x\n", |
|---|
| 1573 | 2138 | readl(base + CIF_MI_CTRL), readl(base + CIF_ISP_CTRL)); |
|---|
| 1574 | 2139 | |
|---|
| 1575 | | - val = rkisp_read(dev, CTRL_VI_ISP_CLK_CTRL, true); |
|---|
| 1576 | 2140 | if (!in_interrupt()) { |
|---|
| 1577 | 2141 | /* normal case */ |
|---|
| 1578 | 2142 | /* check the isp_clk before isp reset operation */ |
|---|
| 1579 | | - old_rate = clk_get_rate(dev->hw_dev->clks[0]); |
|---|
| 1580 | | - safe_rate = dev->hw_dev->clk_rate_tbl[0].clk_rate * 1000000UL; |
|---|
| 2143 | + old_rate = clk_get_rate(hw->clks[0]); |
|---|
| 2144 | + safe_rate = hw->clk_rate_tbl[0].clk_rate * 1000000UL; |
|---|
| 1581 | 2145 | if (old_rate > safe_rate) { |
|---|
| 1582 | | - rkisp_set_clk_rate(dev->hw_dev->clks[0], safe_rate); |
|---|
| 2146 | + rkisp_set_clk_rate(hw->clks[0], safe_rate); |
|---|
| 2147 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 2148 | + rkisp_set_clk_rate(hw->clks[5], safe_rate); |
|---|
| 1583 | 2149 | udelay(100); |
|---|
| 1584 | 2150 | } |
|---|
| 1585 | | - rkisp_soft_reset(dev->hw_dev, false); |
|---|
| 2151 | + rkisp_soft_reset(hw, false); |
|---|
| 1586 | 2152 | } |
|---|
| 1587 | | - rkisp_write(dev, CTRL_VI_ISP_CLK_CTRL, val, true); |
|---|
| 1588 | 2153 | |
|---|
| 1589 | 2154 | if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { |
|---|
| 1590 | 2155 | writel(0, base + CIF_ISP_CSI0_CSI2_RESETN); |
|---|
| .. | .. |
|---|
| 1592 | 2157 | writel(0, base + CIF_ISP_CSI0_MASK1); |
|---|
| 1593 | 2158 | writel(0, base + CIF_ISP_CSI0_MASK2); |
|---|
| 1594 | 2159 | writel(0, base + CIF_ISP_CSI0_MASK3); |
|---|
| 1595 | | - } else if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2160 | + } else if (dev->isp_ver >= ISP_V20) { |
|---|
| 1596 | 2161 | writel(0, base + CSI2RX_CSI2_RESETN); |
|---|
| 2162 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 2163 | + rkisp_next_write(dev, CSI2RX_CSI2_RESETN, 0, true); |
|---|
| 1597 | 2164 | } |
|---|
| 1598 | 2165 | |
|---|
| 1599 | | - dev->hw_dev->is_idle = true; |
|---|
| 1600 | | - dev->hw_dev->is_mi_update = false; |
|---|
| 2166 | + hw->is_dvfs = false; |
|---|
| 2167 | + hw->is_runing = false; |
|---|
| 2168 | + hw->is_idle = true; |
|---|
| 2169 | + hw->is_mi_update = false; |
|---|
| 2170 | + hw->pre_dev_id = -1; |
|---|
| 1601 | 2171 | end: |
|---|
| 1602 | 2172 | dev->irq_ends_mask = 0; |
|---|
| 1603 | 2173 | dev->hdr.op_mode = 0; |
|---|
| 2174 | + dev->sw_rd_cnt = 0; |
|---|
| 2175 | + dev->stats_vdev.rdbk_drop = false; |
|---|
| 1604 | 2176 | rkisp_set_state(&dev->isp_state, ISP_STOP); |
|---|
| 1605 | 2177 | |
|---|
| 1606 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 2178 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 1607 | 2179 | kfifo_reset(&dev->rdbk_kfifo); |
|---|
| 2180 | + if (dev->isp_ver == ISP_V30 || dev->isp_ver == ISP_V32) |
|---|
| 2181 | + memset(&dev->cmsk_cfg, 0, sizeof(dev->cmsk_cfg)); |
|---|
| 1608 | 2182 | if (dev->emd_vc <= CIF_ISP_ADD_DATA_VC_MAX) { |
|---|
| 1609 | 2183 | for (i = 0; i < RKISP_EMDDATA_FIFO_MAX; i++) |
|---|
| 1610 | 2184 | kfifo_free(&dev->emd_data_fifo[i].mipi_kfifo); |
|---|
| .. | .. |
|---|
| 1622 | 2196 | { |
|---|
| 1623 | 2197 | struct rkisp_sensor_info *sensor = dev->active_sensor; |
|---|
| 1624 | 2198 | void __iomem *base = dev->base_addr; |
|---|
| 1625 | | - u32 val; |
|---|
| 1626 | 2199 | bool is_direct = true; |
|---|
| 2200 | + u32 val; |
|---|
| 1627 | 2201 | |
|---|
| 1628 | 2202 | v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 1629 | | - "%s refcnt:%d\n", __func__, |
|---|
| 1630 | | - atomic_read(&dev->hw_dev->refcnt)); |
|---|
| 2203 | + "%s refcnt:%d link_num:%d\n", __func__, |
|---|
| 2204 | + atomic_read(&dev->hw_dev->refcnt), |
|---|
| 2205 | + dev->hw_dev->dev_link_num); |
|---|
| 2206 | + |
|---|
| 2207 | + dev->cap_dev.is_done_early = false; |
|---|
| 2208 | + if (dev->cap_dev.wait_line >= dev->isp_sdev.out_crop.height) |
|---|
| 2209 | + dev->cap_dev.wait_line = 0; |
|---|
| 2210 | + if (dev->cap_dev.wait_line) { |
|---|
| 2211 | + dev->cap_dev.is_done_early = true; |
|---|
| 2212 | + if (dev->isp_ver >= ISP_V32) { |
|---|
| 2213 | + val = dev->cap_dev.wait_line; |
|---|
| 2214 | + rkisp_write(dev, ISP32_ISP_IRQ_CFG0, val << 16, false); |
|---|
| 2215 | + rkisp_set_bits(dev, CIF_ISP_IMSC, 0, ISP3X_OUT_FRM_HALF, false); |
|---|
| 2216 | + } else { |
|---|
| 2217 | + /* using AF 15x15 block */ |
|---|
| 2218 | + val = dev->isp_sdev.out_crop.height / 15; |
|---|
| 2219 | + val = dev->cap_dev.wait_line / val; |
|---|
| 2220 | + val = ISP3X_RAWAF_INELINE0(val) | ISP3X_RAWAF_INTLINE0_EN; |
|---|
| 2221 | + rkisp_unite_write(dev, ISP3X_RAWAF_INT_LINE, val, false); |
|---|
| 2222 | + rkisp_unite_set_bits(dev, ISP_ISP3A_IMSC, 0, ISP2X_3A_RAWAF, false); |
|---|
| 2223 | + rkisp_unite_clear_bits(dev, CIF_ISP_IMSC, ISP2X_LSC_LUT_ERR, false); |
|---|
| 2224 | + dev->rawaf_irq_cnt = 0; |
|---|
| 2225 | + } |
|---|
| 2226 | + } |
|---|
| 1631 | 2227 | |
|---|
| 1632 | 2228 | /* Activate MIPI */ |
|---|
| 1633 | | - if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 2229 | + if (sensor && sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { |
|---|
| 1634 | 2230 | if (dev->isp_ver == ISP_V12 || dev->isp_ver == ISP_V13) { |
|---|
| 1635 | 2231 | /* clear interrupts state */ |
|---|
| 1636 | 2232 | readl(base + CIF_ISP_CSI0_ERR1); |
|---|
| .. | .. |
|---|
| 1645 | 2241 | } |
|---|
| 1646 | 2242 | } |
|---|
| 1647 | 2243 | /* Activate ISP */ |
|---|
| 1648 | | - val = rkisp_read(dev, CIF_ISP_CTRL, false); |
|---|
| 2244 | + val = rkisp_read_reg_cache(dev, CIF_ISP_CTRL); |
|---|
| 1649 | 2245 | val |= CIF_ISP_CTRL_ISP_CFG_UPD | CIF_ISP_CTRL_ISP_ENABLE | |
|---|
| 1650 | 2246 | CIF_ISP_CTRL_ISP_INFORM_ENABLE | CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT; |
|---|
| 1651 | 2247 | if (dev->isp_ver == ISP_V20) |
|---|
| 1652 | 2248 | val |= NOC_HURRY_PRIORITY(2) | NOC_HURRY_W_MODE(2) | NOC_HURRY_R_MODE(1); |
|---|
| 1653 | 2249 | if (atomic_read(&dev->hw_dev->refcnt) > 1) |
|---|
| 1654 | 2250 | is_direct = false; |
|---|
| 1655 | | - rkisp_write(dev, CIF_ISP_CTRL, val, is_direct); |
|---|
| 2251 | + rkisp_unite_write(dev, CIF_ISP_CTRL, val, is_direct); |
|---|
| 2252 | + rkisp_clear_reg_cache_bits(dev, CIF_ISP_CTRL, CIF_ISP_CTRL_ISP_CFG_UPD); |
|---|
| 1656 | 2253 | |
|---|
| 1657 | 2254 | dev->isp_err_cnt = 0; |
|---|
| 1658 | 2255 | dev->isp_isr_cnt = 0; |
|---|
| 1659 | | - dev->isp_state = ISP_START | ISP_FRAME_END; |
|---|
| 1660 | | - dev->irq_ends_mask |= ISP_FRAME_END | ISP_FRAME_IN; |
|---|
| 2256 | + dev->irq_ends_mask |= ISP_FRAME_END; |
|---|
| 1661 | 2257 | dev->irq_ends = 0; |
|---|
| 1662 | 2258 | |
|---|
| 1663 | 2259 | /* XXX: Is the 1000us too long? |
|---|
| .. | .. |
|---|
| 2097 | 2693 | struct rkisp_isp_subdev *isp_sd = sd_to_isp_sd(sd); |
|---|
| 2098 | 2694 | struct rkisp_device *dev = sd_to_isp_dev(sd); |
|---|
| 2099 | 2695 | struct v4l2_rect *crop; |
|---|
| 2100 | | - u32 max_w, max_h; |
|---|
| 2696 | + u32 max_w, max_h, max_size; |
|---|
| 2101 | 2697 | |
|---|
| 2102 | 2698 | if (!sel) |
|---|
| 2103 | 2699 | goto err; |
|---|
| .. | .. |
|---|
| 2118 | 2714 | crop->left = 0; |
|---|
| 2119 | 2715 | crop->top = 0; |
|---|
| 2120 | 2716 | if (sel->pad == RKISP_ISP_PAD_SINK) { |
|---|
| 2121 | | - if (dev->isp_ver == ISP_V12) { |
|---|
| 2717 | + switch (dev->isp_ver) { |
|---|
| 2718 | + case ISP_V12: |
|---|
| 2122 | 2719 | max_w = CIF_ISP_INPUT_W_MAX_V12; |
|---|
| 2123 | 2720 | max_h = CIF_ISP_INPUT_H_MAX_V12; |
|---|
| 2124 | | - } else if (dev->isp_ver == ISP_V13) { |
|---|
| 2721 | + break; |
|---|
| 2722 | + case ISP_V13: |
|---|
| 2125 | 2723 | max_w = CIF_ISP_INPUT_W_MAX_V13; |
|---|
| 2126 | 2724 | max_h = CIF_ISP_INPUT_H_MAX_V13; |
|---|
| 2127 | | - } else if (dev->isp_ver == ISP_V21) { |
|---|
| 2725 | + break; |
|---|
| 2726 | + case ISP_V21: |
|---|
| 2128 | 2727 | max_w = CIF_ISP_INPUT_W_MAX_V21; |
|---|
| 2129 | 2728 | max_h = CIF_ISP_INPUT_H_MAX_V21; |
|---|
| 2130 | | - } else { |
|---|
| 2729 | + break; |
|---|
| 2730 | + case ISP_V30: |
|---|
| 2731 | + max_w = dev->hw_dev->unite ? |
|---|
| 2732 | + CIF_ISP_INPUT_W_MAX_V30_UNITE : CIF_ISP_INPUT_W_MAX_V30; |
|---|
| 2733 | + max_h = dev->hw_dev->unite ? |
|---|
| 2734 | + CIF_ISP_INPUT_H_MAX_V30_UNITE : CIF_ISP_INPUT_H_MAX_V30; |
|---|
| 2735 | + break; |
|---|
| 2736 | + case ISP_V32: |
|---|
| 2737 | + max_w = dev->hw_dev->unite ? |
|---|
| 2738 | + CIF_ISP_INPUT_W_MAX_V32_UNITE : CIF_ISP_INPUT_W_MAX_V32; |
|---|
| 2739 | + max_h = dev->hw_dev->unite ? |
|---|
| 2740 | + CIF_ISP_INPUT_H_MAX_V32_UNITE : CIF_ISP_INPUT_H_MAX_V32; |
|---|
| 2741 | + break; |
|---|
| 2742 | + case ISP_V32_L: |
|---|
| 2743 | + max_w = CIF_ISP_INPUT_W_MAX_V32_L; |
|---|
| 2744 | + max_h = CIF_ISP_INPUT_H_MAX_V32_L; |
|---|
| 2745 | + break; |
|---|
| 2746 | + default: |
|---|
| 2131 | 2747 | max_w = CIF_ISP_INPUT_W_MAX; |
|---|
| 2132 | 2748 | max_h = CIF_ISP_INPUT_H_MAX; |
|---|
| 2133 | 2749 | } |
|---|
| 2750 | + max_size = max_w * max_h; |
|---|
| 2751 | + max_h = max_size / isp_sd->in_frm.width; |
|---|
| 2752 | + |
|---|
| 2134 | 2753 | crop->width = min_t(u32, isp_sd->in_frm.width, max_w); |
|---|
| 2135 | 2754 | crop->height = min_t(u32, isp_sd->in_frm.height, max_h); |
|---|
| 2136 | 2755 | } |
|---|
| .. | .. |
|---|
| 2146 | 2765 | return 0; |
|---|
| 2147 | 2766 | err: |
|---|
| 2148 | 2767 | return -EINVAL; |
|---|
| 2768 | +} |
|---|
| 2769 | + |
|---|
| 2770 | +static void rkisp_check_stream_dcrop(struct rkisp_device *dev, |
|---|
| 2771 | + struct v4l2_rect *crop) |
|---|
| 2772 | +{ |
|---|
| 2773 | + struct rkisp_stream *stream; |
|---|
| 2774 | + struct v4l2_rect *dcrop; |
|---|
| 2775 | + u32 i; |
|---|
| 2776 | + |
|---|
| 2777 | + for (i = 0; i < RKISP_MAX_STREAM; i++) { |
|---|
| 2778 | + if (i != RKISP_STREAM_MP && i != RKISP_STREAM_SP && |
|---|
| 2779 | + i != RKISP_STREAM_FBC && i != RKISP_STREAM_BP) |
|---|
| 2780 | + continue; |
|---|
| 2781 | + stream = &dev->cap_dev.stream[i]; |
|---|
| 2782 | + dcrop = &stream->dcrop; |
|---|
| 2783 | + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 2784 | + "%s id:%d %dx%d(%d %d) from %dx%d(%d %d)\n", |
|---|
| 2785 | + __func__, i, |
|---|
| 2786 | + dcrop->width, dcrop->height, dcrop->left, dcrop->top, |
|---|
| 2787 | + crop->width, crop->height, crop->left, crop->top); |
|---|
| 2788 | + /* make sure dcrop window in isp output window */ |
|---|
| 2789 | + if (dcrop->width > crop->width) { |
|---|
| 2790 | + dcrop->width = crop->width; |
|---|
| 2791 | + dcrop->left = 0; |
|---|
| 2792 | + } else if ((dcrop->left + dcrop->width) > crop->width) { |
|---|
| 2793 | + dcrop->left = crop->width - dcrop->width; |
|---|
| 2794 | + } |
|---|
| 2795 | + if (dcrop->height > crop->height) { |
|---|
| 2796 | + dcrop->height = crop->height; |
|---|
| 2797 | + dcrop->top = 0; |
|---|
| 2798 | + } else if ((dcrop->top + dcrop->height) > crop->height) { |
|---|
| 2799 | + dcrop->top = crop->height - dcrop->height; |
|---|
| 2800 | + } |
|---|
| 2801 | + } |
|---|
| 2149 | 2802 | } |
|---|
| 2150 | 2803 | |
|---|
| 2151 | 2804 | static int rkisp_isp_sd_set_selection(struct v4l2_subdev *sd, |
|---|
| .. | .. |
|---|
| 2179 | 2832 | |
|---|
| 2180 | 2833 | if (sel->pad == RKISP_ISP_PAD_SINK) { |
|---|
| 2181 | 2834 | isp_sd->in_crop = *crop; |
|---|
| 2182 | | - /* ISP20 don't have out crop */ |
|---|
| 2183 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) { |
|---|
| 2835 | + /* don't have out crop */ |
|---|
| 2836 | + if (dev->isp_ver >= ISP_V20) { |
|---|
| 2184 | 2837 | isp_sd->out_crop = *crop; |
|---|
| 2185 | 2838 | isp_sd->out_crop.left = 0; |
|---|
| 2186 | 2839 | isp_sd->out_crop.top = 0; |
|---|
| 2187 | 2840 | dev->br_dev.crop = isp_sd->out_crop; |
|---|
| 2188 | 2841 | } |
|---|
| 2189 | 2842 | } else { |
|---|
| 2190 | | - if (dev->isp_ver == ISP_V20 || dev->isp_ver == ISP_V21) |
|---|
| 2843 | + if (dev->isp_ver >= ISP_V20) |
|---|
| 2191 | 2844 | *crop = isp_sd->out_crop; |
|---|
| 2192 | 2845 | isp_sd->out_crop = *crop; |
|---|
| 2193 | 2846 | } |
|---|
| 2847 | + |
|---|
| 2848 | + rkisp_check_stream_dcrop(dev, crop); |
|---|
| 2194 | 2849 | |
|---|
| 2195 | 2850 | return 0; |
|---|
| 2196 | 2851 | err: |
|---|
| .. | .. |
|---|
| 2246 | 2901 | struct rkisp_stream *stream; |
|---|
| 2247 | 2902 | int i; |
|---|
| 2248 | 2903 | |
|---|
| 2904 | + rkisp_stats_first_ddr_config(&dev->stats_vdev); |
|---|
| 2249 | 2905 | if (dev->hw_dev->is_mi_update) |
|---|
| 2250 | 2906 | return; |
|---|
| 2251 | 2907 | |
|---|
| 2252 | | - rkisp_stats_first_ddr_config(&dev->stats_vdev); |
|---|
| 2253 | 2908 | rkisp_config_dmatx_valid_buf(dev); |
|---|
| 2254 | 2909 | |
|---|
| 2255 | 2910 | force_cfg_update(dev); |
|---|
| 2256 | 2911 | |
|---|
| 2257 | 2912 | hdr_update_dmatx_buf(dev); |
|---|
| 2258 | | - if (dev->br_dev.en && dev->isp_ver == ISP_V20) { |
|---|
| 2259 | | - stream = &dev->cap_dev.stream[RKISP_STREAM_SP]; |
|---|
| 2260 | | - rkisp_update_spstream_buf(stream); |
|---|
| 2261 | | - } |
|---|
| 2262 | 2913 | if (dev->hw_dev->is_single) { |
|---|
| 2263 | 2914 | for (i = 0; i < RKISP_MAX_STREAM; i++) { |
|---|
| 2264 | 2915 | stream = &dev->cap_dev.stream[i]; |
|---|
| 2265 | | - if (stream->streaming && !stream->next_buf) |
|---|
| 2266 | | - stream->ops->frame_end(stream); |
|---|
| 2916 | + if (stream->id == RKISP_STREAM_VIR || |
|---|
| 2917 | + stream->id == RKISP_STREAM_LUMA) |
|---|
| 2918 | + continue; |
|---|
| 2919 | + if (stream->streaming && !stream->curr_buf) |
|---|
| 2920 | + stream->ops->frame_end(stream, FRAME_INIT); |
|---|
| 2267 | 2921 | } |
|---|
| 2268 | 2922 | } |
|---|
| 2923 | + rkisp_stats_next_ddr_config(&dev->stats_vdev); |
|---|
| 2269 | 2924 | } |
|---|
| 2270 | 2925 | |
|---|
| 2271 | 2926 | static int rkisp_isp_sd_s_stream(struct v4l2_subdev *sd, int on) |
|---|
| 2272 | 2927 | { |
|---|
| 2273 | 2928 | struct rkisp_device *isp_dev = sd_to_isp_dev(sd); |
|---|
| 2929 | + struct rkisp_hw_dev *hw_dev = isp_dev->hw_dev; |
|---|
| 2274 | 2930 | |
|---|
| 2275 | 2931 | if (!on) { |
|---|
| 2932 | + if (IS_HDR_RDBK(isp_dev->rd_mode)) { |
|---|
| 2933 | + struct rkisp_stream *s; |
|---|
| 2934 | + int i; |
|---|
| 2935 | + |
|---|
| 2936 | + for (i = RKISP_STREAM_RAWRD0; i <= RKISP_STREAM_RAWRD2; i++) { |
|---|
| 2937 | + s = &isp_dev->dmarx_dev.stream[i]; |
|---|
| 2938 | + if (s->stopping) |
|---|
| 2939 | + wake_up(&s->done); |
|---|
| 2940 | + } |
|---|
| 2941 | + } |
|---|
| 2276 | 2942 | wait_event_timeout(isp_dev->sync_onoff, |
|---|
| 2277 | | - isp_dev->irq_ends_mask == (ISP_FRAME_END | ISP_FRAME_IN) && |
|---|
| 2278 | | - (!IS_HDR_RDBK(isp_dev->rd_mode) || |
|---|
| 2279 | | - isp_dev->isp_state & ISP_STOP), msecs_to_jiffies(5)); |
|---|
| 2943 | + isp_dev->isp_state & ISP_STOP || |
|---|
| 2944 | + !IS_HDR_RDBK(isp_dev->rd_mode), |
|---|
| 2945 | + msecs_to_jiffies(50)); |
|---|
| 2280 | 2946 | rkisp_isp_stop(isp_dev); |
|---|
| 2281 | | - atomic_dec(&isp_dev->hw_dev->refcnt); |
|---|
| 2947 | + atomic_dec(&hw_dev->refcnt); |
|---|
| 2282 | 2948 | rkisp_params_stream_stop(&isp_dev->params_vdev); |
|---|
| 2949 | + atomic_set(&isp_dev->isp_sdev.frm_sync_seq, 0); |
|---|
| 2283 | 2950 | rkisp_stop_3a_run(isp_dev); |
|---|
| 2284 | 2951 | return 0; |
|---|
| 2285 | 2952 | } |
|---|
| 2286 | 2953 | |
|---|
| 2954 | + hw_dev->is_runing = true; |
|---|
| 2287 | 2955 | rkisp_start_3a_run(isp_dev); |
|---|
| 2288 | 2956 | memset(&isp_dev->isp_sdev.dbg, 0, sizeof(isp_dev->isp_sdev.dbg)); |
|---|
| 2289 | | - atomic_inc(&isp_dev->hw_dev->refcnt); |
|---|
| 2290 | | - atomic_set(&isp_dev->isp_sdev.frm_sync_seq, 0); |
|---|
| 2291 | | - rkisp_global_update_mi(isp_dev); |
|---|
| 2957 | + if (atomic_inc_return(&hw_dev->refcnt) > hw_dev->dev_link_num) { |
|---|
| 2958 | + dev_err(isp_dev->dev, "%s fail: input link before hw start\n", __func__); |
|---|
| 2959 | + atomic_dec(&hw_dev->refcnt); |
|---|
| 2960 | + return -EINVAL; |
|---|
| 2961 | + } |
|---|
| 2962 | + |
|---|
| 2292 | 2963 | rkisp_config_cif(isp_dev); |
|---|
| 2293 | 2964 | rkisp_isp_start(isp_dev); |
|---|
| 2965 | + rkisp_global_update_mi(isp_dev); |
|---|
| 2966 | + isp_dev->isp_state = ISP_START | ISP_FRAME_END; |
|---|
| 2294 | 2967 | rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, NULL); |
|---|
| 2295 | 2968 | return 0; |
|---|
| 2969 | +} |
|---|
| 2970 | + |
|---|
| 2971 | +static void rkisp_rx_buf_free(struct rkisp_device *dev, struct rkisp_rx_buf *dbufs) |
|---|
| 2972 | +{ |
|---|
| 2973 | + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; |
|---|
| 2974 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 2975 | + int i = 0; |
|---|
| 2976 | + |
|---|
| 2977 | + if (!dbufs) |
|---|
| 2978 | + return; |
|---|
| 2979 | + |
|---|
| 2980 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 2981 | + pool = &dev->pv_pool[i]; |
|---|
| 2982 | + if (dbufs == pool->dbufs) { |
|---|
| 2983 | + if (pool->mem_priv) { |
|---|
| 2984 | + g_ops->unmap_dmabuf(pool->mem_priv); |
|---|
| 2985 | + g_ops->detach_dmabuf(pool->mem_priv); |
|---|
| 2986 | + dma_buf_put(pool->dbufs->dbuf); |
|---|
| 2987 | + pool->mem_priv = NULL; |
|---|
| 2988 | + } |
|---|
| 2989 | + pool->dbufs = NULL; |
|---|
| 2990 | + break; |
|---|
| 2991 | + } |
|---|
| 2992 | + } |
|---|
| 2993 | +} |
|---|
| 2994 | + |
|---|
| 2995 | +static void rkisp_rx_qbuf_online(struct rkisp_stream *stream, |
|---|
| 2996 | + struct rkisp_rx_buf_pool *pool) |
|---|
| 2997 | +{ |
|---|
| 2998 | + struct rkisp_device *dev = stream->ispdev; |
|---|
| 2999 | + u32 val = pool->buf.buff_addr[RKISP_PLANE_Y]; |
|---|
| 3000 | + |
|---|
| 3001 | + rkisp_write(dev, stream->config->mi.y_base_ad_init, val, false); |
|---|
| 3002 | + if (dev->hw_dev->unite == ISP_UNITE_TWO) { |
|---|
| 3003 | + u32 offs = stream->out_fmt.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 3004 | + |
|---|
| 3005 | + if (stream->memory) |
|---|
| 3006 | + offs *= DIV_ROUND_UP(stream->out_isp_fmt.bpp[0], 8); |
|---|
| 3007 | + else |
|---|
| 3008 | + offs = offs * stream->out_isp_fmt.bpp[0] / 8; |
|---|
| 3009 | + val += offs; |
|---|
| 3010 | + rkisp_next_write(dev, stream->config->mi.y_base_ad_init, val, false); |
|---|
| 3011 | + } |
|---|
| 3012 | +} |
|---|
| 3013 | + |
|---|
| 3014 | +static void rkisp_rx_qbuf_rdbk(struct rkisp_stream *stream, |
|---|
| 3015 | + struct rkisp_rx_buf_pool *pool) |
|---|
| 3016 | +{ |
|---|
| 3017 | + struct rkisp_device *dev = stream->ispdev; |
|---|
| 3018 | + unsigned long lock_flags = 0; |
|---|
| 3019 | + struct rkisp_buffer *ispbuf = &pool->buf; |
|---|
| 3020 | + struct isp2x_csi_trigger trigger = { |
|---|
| 3021 | + .frame_timestamp = ispbuf->vb.vb2_buf.timestamp, |
|---|
| 3022 | + .sof_timestamp = ispbuf->vb.vb2_buf.timestamp, |
|---|
| 3023 | + .frame_id = ispbuf->vb.sequence, |
|---|
| 3024 | + .mode = 0, |
|---|
| 3025 | + .times = 0, |
|---|
| 3026 | + }; |
|---|
| 3027 | + spin_lock_irqsave(&stream->vbq_lock, lock_flags); |
|---|
| 3028 | + if (list_empty(&stream->buf_queue) && !stream->curr_buf) { |
|---|
| 3029 | + stream->curr_buf = ispbuf; |
|---|
| 3030 | + stream->ops->update_mi(stream); |
|---|
| 3031 | + } else { |
|---|
| 3032 | + list_add_tail(&ispbuf->queue, &stream->buf_queue); |
|---|
| 3033 | + } |
|---|
| 3034 | + spin_unlock_irqrestore(&stream->vbq_lock, lock_flags); |
|---|
| 3035 | + if (stream->id == RKISP_STREAM_RAWRD2) |
|---|
| 3036 | + rkisp_rdbk_trigger_event(dev, T_CMD_QUEUE, &trigger); |
|---|
| 3037 | +} |
|---|
| 3038 | + |
|---|
| 3039 | +static int rkisp_rx_qbuf(struct rkisp_device *dev, |
|---|
| 3040 | + struct rkisp_rx_buf *dbufs) |
|---|
| 3041 | +{ |
|---|
| 3042 | + struct rkisp_stream *stream; |
|---|
| 3043 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 3044 | + int i; |
|---|
| 3045 | + |
|---|
| 3046 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 3047 | + pool = &dev->pv_pool[i]; |
|---|
| 3048 | + if (dbufs == pool->dbufs) |
|---|
| 3049 | + break; |
|---|
| 3050 | + } |
|---|
| 3051 | + |
|---|
| 3052 | + if (pool->dbufs == NULL || pool->dbufs != dbufs) |
|---|
| 3053 | + return -EINVAL; |
|---|
| 3054 | + switch (dbufs->type) { |
|---|
| 3055 | + case BUF_SHORT: |
|---|
| 3056 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2]; |
|---|
| 3057 | + break; |
|---|
| 3058 | + case BUF_MIDDLE: |
|---|
| 3059 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0]; |
|---|
| 3060 | + break; |
|---|
| 3061 | + case BUF_LONG: |
|---|
| 3062 | + default: |
|---|
| 3063 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1]; |
|---|
| 3064 | + } |
|---|
| 3065 | + |
|---|
| 3066 | + v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev, |
|---|
| 3067 | + "%s rd_mode:%d seq:%d dma:0x%x\n", |
|---|
| 3068 | + __func__, dev->rd_mode, dbufs->sequence, |
|---|
| 3069 | + pool->buf.buff_addr[RKISP_PLANE_Y]); |
|---|
| 3070 | + |
|---|
| 3071 | + if (!IS_HDR_RDBK(dev->rd_mode)) { |
|---|
| 3072 | + rkisp_rx_qbuf_online(stream, pool); |
|---|
| 3073 | + } else { |
|---|
| 3074 | + pool->buf.vb.vb2_buf.timestamp = dbufs->timestamp; |
|---|
| 3075 | + pool->buf.vb.sequence = dbufs->sequence; |
|---|
| 3076 | + rkisp_rx_qbuf_rdbk(stream, pool); |
|---|
| 3077 | + } |
|---|
| 3078 | + return 0; |
|---|
| 3079 | +} |
|---|
| 3080 | + |
|---|
| 3081 | +void rkisp_rx_buf_pool_free(struct rkisp_device *dev) |
|---|
| 3082 | +{ |
|---|
| 3083 | + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; |
|---|
| 3084 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 3085 | + int i; |
|---|
| 3086 | + |
|---|
| 3087 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 3088 | + pool = &dev->pv_pool[i]; |
|---|
| 3089 | + if (!pool->dbufs) |
|---|
| 3090 | + break; |
|---|
| 3091 | + if (pool->mem_priv) { |
|---|
| 3092 | + g_ops->unmap_dmabuf(pool->mem_priv); |
|---|
| 3093 | + g_ops->detach_dmabuf(pool->mem_priv); |
|---|
| 3094 | + dma_buf_put(pool->dbufs->dbuf); |
|---|
| 3095 | + pool->mem_priv = NULL; |
|---|
| 3096 | + } |
|---|
| 3097 | + pool->dbufs = NULL; |
|---|
| 3098 | + } |
|---|
| 3099 | +} |
|---|
| 3100 | + |
|---|
| 3101 | +static int rkisp_rx_buf_pool_init(struct rkisp_device *dev, |
|---|
| 3102 | + struct rkisp_rx_buf *dbufs) |
|---|
| 3103 | +{ |
|---|
| 3104 | + const struct vb2_mem_ops *g_ops = dev->hw_dev->mem_ops; |
|---|
| 3105 | + struct rkisp_stream *stream; |
|---|
| 3106 | + struct rkisp_rx_buf_pool *pool; |
|---|
| 3107 | + struct sg_table *sg_tbl; |
|---|
| 3108 | + dma_addr_t dma; |
|---|
| 3109 | + int i, ret; |
|---|
| 3110 | + void *mem, *vaddr = NULL; |
|---|
| 3111 | + |
|---|
| 3112 | + for (i = 0; i < RKISP_RX_BUF_POOL_MAX; i++) { |
|---|
| 3113 | + pool = &dev->pv_pool[i]; |
|---|
| 3114 | + if (!pool->dbufs) |
|---|
| 3115 | + break; |
|---|
| 3116 | + } |
|---|
| 3117 | + |
|---|
| 3118 | + pool->dbufs = dbufs; |
|---|
| 3119 | + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 3120 | + "%s type:0x%x dbufs[%d]:%p", __func__, dbufs->type, i, dbufs); |
|---|
| 3121 | + |
|---|
| 3122 | + if (dbufs->is_resmem) { |
|---|
| 3123 | + dma = dbufs->dma; |
|---|
| 3124 | + goto end; |
|---|
| 3125 | + } |
|---|
| 3126 | + mem = g_ops->attach_dmabuf(dev->hw_dev->dev, dbufs->dbuf, |
|---|
| 3127 | + dbufs->dbuf->size, DMA_BIDIRECTIONAL); |
|---|
| 3128 | + if (IS_ERR(mem)) { |
|---|
| 3129 | + ret = PTR_ERR(mem); |
|---|
| 3130 | + goto err; |
|---|
| 3131 | + } |
|---|
| 3132 | + pool->mem_priv = mem; |
|---|
| 3133 | + ret = g_ops->map_dmabuf(mem); |
|---|
| 3134 | + if (ret) |
|---|
| 3135 | + goto err; |
|---|
| 3136 | + if (dev->hw_dev->is_dma_sg_ops) { |
|---|
| 3137 | + sg_tbl = (struct sg_table *)g_ops->cookie(mem); |
|---|
| 3138 | + dma = sg_dma_address(sg_tbl->sgl); |
|---|
| 3139 | + } else { |
|---|
| 3140 | + dma = *((dma_addr_t *)g_ops->cookie(mem)); |
|---|
| 3141 | + } |
|---|
| 3142 | + get_dma_buf(dbufs->dbuf); |
|---|
| 3143 | + vaddr = g_ops->vaddr(mem); |
|---|
| 3144 | +end: |
|---|
| 3145 | + dbufs->is_init = true; |
|---|
| 3146 | + pool->buf.other = dbufs; |
|---|
| 3147 | + pool->buf.buff_addr[RKISP_PLANE_Y] = dma; |
|---|
| 3148 | + pool->buf.vaddr[RKISP_PLANE_Y] = vaddr; |
|---|
| 3149 | + |
|---|
| 3150 | + switch (dbufs->type) { |
|---|
| 3151 | + case BUF_SHORT: |
|---|
| 3152 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD2]; |
|---|
| 3153 | + break; |
|---|
| 3154 | + case BUF_MIDDLE: |
|---|
| 3155 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD0]; |
|---|
| 3156 | + break; |
|---|
| 3157 | + case BUF_LONG: |
|---|
| 3158 | + default: |
|---|
| 3159 | + stream = &dev->dmarx_dev.stream[RKISP_STREAM_RAWRD1]; |
|---|
| 3160 | + } |
|---|
| 3161 | + if (dbufs->is_first) { |
|---|
| 3162 | + stream->memory = 0; |
|---|
| 3163 | + if (dbufs->is_uncompact) |
|---|
| 3164 | + stream->memory = SW_CSI_RAW_WR_SIMG_MODE; |
|---|
| 3165 | + rkisp_dmarx_set_fmt(stream, stream->out_fmt); |
|---|
| 3166 | + stream->ops->config_mi(stream); |
|---|
| 3167 | + dbufs->is_first = false; |
|---|
| 3168 | + } |
|---|
| 3169 | + v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 3170 | + "%s dma:0x%x vaddr:%p", __func__, (u32)dma, vaddr); |
|---|
| 3171 | + return 0; |
|---|
| 3172 | +err: |
|---|
| 3173 | + rkisp_rx_buf_pool_free(dev); |
|---|
| 3174 | + return ret; |
|---|
| 3175 | +} |
|---|
| 3176 | + |
|---|
| 3177 | +static int rkisp_sd_s_rx_buffer(struct v4l2_subdev *sd, |
|---|
| 3178 | + void *buf, unsigned int *size) |
|---|
| 3179 | +{ |
|---|
| 3180 | + struct rkisp_device *dev = sd_to_isp_dev(sd); |
|---|
| 3181 | + struct rkisp_rx_buf *dbufs; |
|---|
| 3182 | + int ret = 0; |
|---|
| 3183 | + |
|---|
| 3184 | + if (!buf) |
|---|
| 3185 | + return -EINVAL; |
|---|
| 3186 | + |
|---|
| 3187 | + dbufs = buf; |
|---|
| 3188 | + if (!dbufs->is_init) |
|---|
| 3189 | + ret = rkisp_rx_buf_pool_init(dev, dbufs); |
|---|
| 3190 | + if (!ret) |
|---|
| 3191 | + ret = rkisp_rx_qbuf(dev, dbufs); |
|---|
| 3192 | + |
|---|
| 3193 | + return ret; |
|---|
| 2296 | 3194 | } |
|---|
| 2297 | 3195 | |
|---|
| 2298 | 3196 | static int rkisp_isp_sd_s_power(struct v4l2_subdev *sd, int on) |
|---|
| .. | .. |
|---|
| 2300 | 3198 | struct rkisp_device *isp_dev = sd_to_isp_dev(sd); |
|---|
| 2301 | 3199 | int ret; |
|---|
| 2302 | 3200 | |
|---|
| 2303 | | - if (isp_dev->hw_dev->is_thunderboot) |
|---|
| 2304 | | - return 0; |
|---|
| 2305 | | - |
|---|
| 2306 | 3201 | v4l2_dbg(1, rkisp_debug, &isp_dev->v4l2_dev, |
|---|
| 2307 | 3202 | "%s on:%d\n", __func__, on); |
|---|
| 2308 | 3203 | |
|---|
| 2309 | 3204 | if (on) { |
|---|
| 2310 | | - if (isp_dev->isp_ver == ISP_V20 || isp_dev->isp_ver == ISP_V21) |
|---|
| 3205 | + if (isp_dev->isp_ver >= ISP_V20) |
|---|
| 2311 | 3206 | kfifo_reset(&isp_dev->rdbk_kfifo); |
|---|
| 2312 | 3207 | ret = pm_runtime_get_sync(isp_dev->dev); |
|---|
| 2313 | 3208 | } else { |
|---|
| .. | .. |
|---|
| 2337 | 3232 | dev = sd_to_isp_dev(sd); |
|---|
| 2338 | 3233 | if (!dev) |
|---|
| 2339 | 3234 | return -ENODEV; |
|---|
| 3235 | + |
|---|
| 3236 | + if (dev->hw_dev->is_runing && |
|---|
| 3237 | + (!dev->isp_inp || |
|---|
| 3238 | + !(dev->isp_inp & ~rawrd) || |
|---|
| 3239 | + !strcmp(remote->entity->name, CSI_DEV_NAME) || |
|---|
| 3240 | + strstr(remote->entity->name, "rkcif"))) { |
|---|
| 3241 | + v4l2_err(sd, "no support link for isp hw working\n"); |
|---|
| 3242 | + return -EINVAL; |
|---|
| 3243 | + } |
|---|
| 2340 | 3244 | |
|---|
| 2341 | 3245 | if (!strcmp(remote->entity->name, DMA_VDEV_NAME)) { |
|---|
| 2342 | 3246 | stream = &dev->dmarx_dev.stream[RKISP_STREAM_DMARX]; |
|---|
| .. | .. |
|---|
| 2386 | 3290 | } else { |
|---|
| 2387 | 3291 | dev->isp_inp &= ~INP_RAWRD2; |
|---|
| 2388 | 3292 | } |
|---|
| 3293 | + } else if (!strcmp(remote->entity->name, FBC_VDEV_NAME)) { |
|---|
| 3294 | + stream = &dev->cap_dev.stream[RKISP_STREAM_FBC]; |
|---|
| 3295 | + } else if (!strcmp(remote->entity->name, BP_VDEV_NAME)) { |
|---|
| 3296 | + stream = &dev->cap_dev.stream[RKISP_STREAM_BP]; |
|---|
| 3297 | + } else if (!strcmp(remote->entity->name, MPDS_VDEV_NAME)) { |
|---|
| 3298 | + stream = &dev->cap_dev.stream[RKISP_STREAM_MPDS]; |
|---|
| 3299 | + } else if (!strcmp(remote->entity->name, BPDS_VDEV_NAME)) { |
|---|
| 3300 | + stream = &dev->cap_dev.stream[RKISP_STREAM_BPDS]; |
|---|
| 3301 | + } else if (!strcmp(remote->entity->name, LUMA_VDEV_NAME)) { |
|---|
| 3302 | + stream = &dev->cap_dev.stream[RKISP_STREAM_LUMA]; |
|---|
| 3303 | + } else if (!strcmp(remote->entity->name, VIR_VDEV_NAME)) { |
|---|
| 3304 | + stream = &dev->cap_dev.stream[RKISP_STREAM_VIR]; |
|---|
| 2389 | 3305 | } else if (!strcmp(remote->entity->name, SP_VDEV_NAME)) { |
|---|
| 2390 | 3306 | stream = &dev->cap_dev.stream[RKISP_STREAM_SP]; |
|---|
| 2391 | 3307 | } else if (!strcmp(remote->entity->name, MP_VDEV_NAME)) { |
|---|
| .. | .. |
|---|
| 2430 | 3346 | |
|---|
| 2431 | 3347 | if (stream) |
|---|
| 2432 | 3348 | stream->linked = flags & MEDIA_LNK_FL_ENABLED; |
|---|
| 2433 | | - if (dev->isp_inp & rawrd) |
|---|
| 3349 | + if (dev->isp_inp & rawrd) { |
|---|
| 2434 | 3350 | dev->dmarx_dev.trigger = T_MANUAL; |
|---|
| 2435 | | - else |
|---|
| 3351 | + dev->is_rdbk_auto = false; |
|---|
| 3352 | + } else { |
|---|
| 2436 | 3353 | dev->dmarx_dev.trigger = T_AUTO; |
|---|
| 3354 | + } |
|---|
| 3355 | + if (dev->isp_inp & INP_CIF) { |
|---|
| 3356 | + struct v4l2_subdev *remote = get_remote_sensor(sd); |
|---|
| 3357 | + struct rkisp_vicap_mode mode; |
|---|
| 2437 | 3358 | |
|---|
| 3359 | + memset(&mode, 0, sizeof(mode)); |
|---|
| 3360 | + mode.name = dev->name; |
|---|
| 3361 | + mode.rdbk_mode = !!(dev->isp_inp & rawrd); |
|---|
| 3362 | + /* read back mode only */ |
|---|
| 3363 | + if (dev->isp_ver < ISP_V30 || !dev->hw_dev->is_single) |
|---|
| 3364 | + mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ; |
|---|
| 3365 | + v4l2_subdev_call(remote, core, ioctl, |
|---|
| 3366 | + RKISP_VICAP_CMD_MODE, &mode); |
|---|
| 3367 | + dev->vicap_in = mode.input; |
|---|
| 3368 | + } |
|---|
| 3369 | + |
|---|
| 3370 | + if (!dev->isp_inp) |
|---|
| 3371 | + dev->is_hw_link = false; |
|---|
| 3372 | + else |
|---|
| 3373 | + dev->is_hw_link = true; |
|---|
| 2438 | 3374 | v4l2_dbg(1, rkisp_debug, &dev->v4l2_dev, |
|---|
| 2439 | 3375 | "isp input:0x%x\n", dev->isp_inp); |
|---|
| 2440 | 3376 | return 0; |
|---|
| .. | .. |
|---|
| 2482 | 3418 | atomic_inc_return(&isp->frm_sync_seq) - 1, |
|---|
| 2483 | 3419 | }; |
|---|
| 2484 | 3420 | |
|---|
| 2485 | | - event.timestamp = ns_to_timespec(ktime_get_ns()); |
|---|
| 2486 | 3421 | v4l2_event_queue(isp->sd.devnode, &event); |
|---|
| 2487 | 3422 | } |
|---|
| 2488 | 3423 | |
|---|
| .. | .. |
|---|
| 2499 | 3434 | return v4l2_event_subscribe(fh, sub, ISP_V4L2_EVENT_ELEMS, NULL); |
|---|
| 2500 | 3435 | } |
|---|
| 2501 | 3436 | |
|---|
| 3437 | +static int rkisp_get_info(struct rkisp_device *dev, struct rkisp_isp_info *info) |
|---|
| 3438 | +{ |
|---|
| 3439 | + struct v4l2_rect *in_crop = &dev->isp_sdev.in_crop; |
|---|
| 3440 | + u32 rd_mode, mode = 0, bit = 0; |
|---|
| 3441 | + int ret; |
|---|
| 3442 | + |
|---|
| 3443 | + if (!(dev->isp_state & ISP_START)) { |
|---|
| 3444 | + struct rkmodule_hdr_cfg cfg; |
|---|
| 3445 | + |
|---|
| 3446 | + ret = rkisp_csi_get_hdr_cfg(dev, &cfg); |
|---|
| 3447 | + if (ret) |
|---|
| 3448 | + return ret; |
|---|
| 3449 | + rd_mode = cfg.hdr_mode; |
|---|
| 3450 | + if (rd_mode == HDR_COMPR) |
|---|
| 3451 | + bit = cfg.compr.bit > 20 ? 20 : cfg.compr.bit; |
|---|
| 3452 | + } else { |
|---|
| 3453 | + rd_mode = dev->rd_mode; |
|---|
| 3454 | + bit = dev->hdr.compr_bit; |
|---|
| 3455 | + } |
|---|
| 3456 | + |
|---|
| 3457 | + switch (rd_mode) { |
|---|
| 3458 | + case HDR_RDBK_FRAME2: |
|---|
| 3459 | + case HDR_FRAMEX2_DDR: |
|---|
| 3460 | + case HDR_LINEX2_DDR: |
|---|
| 3461 | + mode = RKISP_ISP_HDR2; |
|---|
| 3462 | + break; |
|---|
| 3463 | + case HDR_RDBK_FRAME3: |
|---|
| 3464 | + case HDR_FRAMEX3_DDR: |
|---|
| 3465 | + case HDR_LINEX3_DDR: |
|---|
| 3466 | + mode = RKISP_ISP_HDR3; |
|---|
| 3467 | + break; |
|---|
| 3468 | + default: |
|---|
| 3469 | + mode = RKISP_ISP_NORMAL; |
|---|
| 3470 | + } |
|---|
| 3471 | + if (bit) |
|---|
| 3472 | + mode = RKISP_ISP_COMPR; |
|---|
| 3473 | + info->compr_bit = bit; |
|---|
| 3474 | + |
|---|
| 3475 | + if (dev->is_bigmode) |
|---|
| 3476 | + mode |= RKISP_ISP_BIGMODE; |
|---|
| 3477 | + info->mode = mode; |
|---|
| 3478 | + if (dev->hw_dev->unite) |
|---|
| 3479 | + info->act_width = in_crop->width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL; |
|---|
| 3480 | + else |
|---|
| 3481 | + info->act_width = in_crop->width; |
|---|
| 3482 | + info->act_height = in_crop->height; |
|---|
| 3483 | + return 0; |
|---|
| 3484 | +} |
|---|
| 3485 | + |
|---|
| 2502 | 3486 | static long rkisp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) |
|---|
| 2503 | 3487 | { |
|---|
| 2504 | 3488 | struct rkisp_device *isp_dev = sd_to_isp_dev(sd); |
|---|
| 2505 | 3489 | struct rkisp_thunderboot_resmem *resmem; |
|---|
| 3490 | + struct rkisp32_thunderboot_resmem_head *tb_head_v32; |
|---|
| 2506 | 3491 | struct rkisp_thunderboot_resmem_head *head; |
|---|
| 2507 | 3492 | struct rkisp_thunderboot_shmem *shmem; |
|---|
| 2508 | 3493 | struct isp2x_buf_idxfd *idxfd; |
|---|
| 3494 | + struct rkisp_rx_buf *dbufs; |
|---|
| 2509 | 3495 | void *resmem_va; |
|---|
| 2510 | 3496 | long ret = 0; |
|---|
| 2511 | 3497 | |
|---|
| 2512 | | - if (!arg && cmd != RKISP_CMD_FREE_SHARED_BUF) |
|---|
| 3498 | + if (!arg && |
|---|
| 3499 | + (cmd != RKISP_CMD_FREE_SHARED_BUF && |
|---|
| 3500 | + cmd != RKISP_CMD_MULTI_DEV_FORCE_ENUM)) |
|---|
| 2513 | 3501 | return -EINVAL; |
|---|
| 2514 | 3502 | |
|---|
| 2515 | 3503 | switch (cmd) { |
|---|
| 2516 | 3504 | case RKISP_CMD_TRIGGER_READ_BACK: |
|---|
| 2517 | 3505 | rkisp_rdbk_trigger_event(isp_dev, T_CMD_QUEUE, arg); |
|---|
| 2518 | 3506 | break; |
|---|
| 3507 | + case RKISP_CMD_GET_ISP_INFO: |
|---|
| 3508 | + rkisp_get_info(isp_dev, arg); |
|---|
| 3509 | + break; |
|---|
| 3510 | + case RKISP_CMD_GET_TB_HEAD_V32: |
|---|
| 3511 | + if (isp_dev->tb_head.complete != RKISP_TB_OK || !isp_dev->is_pre_on) { |
|---|
| 3512 | + ret = -EINVAL; |
|---|
| 3513 | + break; |
|---|
| 3514 | + } |
|---|
| 3515 | + tb_head_v32 = arg; |
|---|
| 3516 | + memcpy(tb_head_v32, &isp_dev->tb_head, |
|---|
| 3517 | + sizeof(struct rkisp_thunderboot_resmem_head)); |
|---|
| 3518 | + memcpy(&tb_head_v32->cfg, isp_dev->params_vdev.isp32_params, |
|---|
| 3519 | + sizeof(struct isp32_isp_params_cfg)); |
|---|
| 3520 | + break; |
|---|
| 2519 | 3521 | case RKISP_CMD_GET_SHARED_BUF: |
|---|
| 3522 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3523 | + ret = -ENOIOCTLCMD; |
|---|
| 3524 | + break; |
|---|
| 3525 | + } |
|---|
| 2520 | 3526 | resmem = (struct rkisp_thunderboot_resmem *)arg; |
|---|
| 2521 | 3527 | resmem->resmem_padr = isp_dev->resmem_pa; |
|---|
| 2522 | 3528 | resmem->resmem_size = isp_dev->resmem_size; |
|---|
| .. | .. |
|---|
| 2546 | 3552 | } |
|---|
| 2547 | 3553 | break; |
|---|
| 2548 | 3554 | case RKISP_CMD_FREE_SHARED_BUF: |
|---|
| 3555 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3556 | + ret = -ENOIOCTLCMD; |
|---|
| 3557 | + break; |
|---|
| 3558 | + } |
|---|
| 2549 | 3559 | if (isp_dev->resmem_pa && isp_dev->resmem_size) { |
|---|
| 2550 | 3560 | dma_unmap_single(isp_dev->dev, isp_dev->resmem_pa, |
|---|
| 2551 | 3561 | sizeof(struct rkisp_thunderboot_resmem_head), |
|---|
| .. | .. |
|---|
| 2564 | 3574 | break; |
|---|
| 2565 | 3575 | case RKISP_CMD_SET_LDCHBUF_SIZE: |
|---|
| 2566 | 3576 | case RKISP_CMD_SET_MESHBUF_SIZE: |
|---|
| 2567 | | - rkisp_params_set_meshbuf_size(&isp_dev->params_vdev, arg); |
|---|
| 3577 | + ret = rkisp_params_set_meshbuf_size(&isp_dev->params_vdev, arg); |
|---|
| 2568 | 3578 | break; |
|---|
| 2569 | 3579 | case RKISP_CMD_GET_SHM_BUFFD: |
|---|
| 3580 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3581 | + ret = -ENOIOCTLCMD; |
|---|
| 3582 | + break; |
|---|
| 3583 | + } |
|---|
| 2570 | 3584 | shmem = (struct rkisp_thunderboot_shmem *)arg; |
|---|
| 2571 | 3585 | ret = rkisp_tb_shm_ioctl(shmem); |
|---|
| 2572 | 3586 | break; |
|---|
| 2573 | 3587 | case RKISP_CMD_GET_FBCBUF_FD: |
|---|
| 2574 | 3588 | idxfd = (struct isp2x_buf_idxfd *)arg; |
|---|
| 2575 | 3589 | ret = rkisp_bridge_get_fbcbuf_fd(isp_dev, idxfd); |
|---|
| 3590 | + break; |
|---|
| 3591 | + case RKISP_CMD_INFO2DDR: |
|---|
| 3592 | + ret = rkisp_params_info2ddr_cfg(&isp_dev->params_vdev, arg); |
|---|
| 3593 | + break; |
|---|
| 3594 | + case RKISP_CMD_MESHBUF_FREE: |
|---|
| 3595 | + rkisp_params_meshbuf_free(&isp_dev->params_vdev, *(u64 *)arg); |
|---|
| 3596 | + break; |
|---|
| 3597 | + case RKISP_VICAP_CMD_RX_BUFFER_FREE: |
|---|
| 3598 | + dbufs = (struct rkisp_rx_buf *)arg; |
|---|
| 3599 | + rkisp_rx_buf_free(isp_dev, dbufs); |
|---|
| 3600 | + break; |
|---|
| 3601 | + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: |
|---|
| 3602 | + if (isp_dev->hw_dev->is_runing) { |
|---|
| 3603 | + ret = -EINVAL; |
|---|
| 3604 | + } else { |
|---|
| 3605 | + isp_dev->hw_dev->is_single = true; |
|---|
| 3606 | + isp_dev->hw_dev->is_multi_overflow = false; |
|---|
| 3607 | + rkisp_hw_enum_isp_size(isp_dev->hw_dev); |
|---|
| 3608 | + } |
|---|
| 2576 | 3609 | break; |
|---|
| 2577 | 3610 | default: |
|---|
| 2578 | 3611 | ret = -ENOIOCTLCMD; |
|---|
| .. | .. |
|---|
| 2594 | 3627 | struct rkisp_meshbuf_size meshsize; |
|---|
| 2595 | 3628 | struct rkisp_thunderboot_shmem shmem; |
|---|
| 2596 | 3629 | struct isp2x_buf_idxfd idxfd; |
|---|
| 3630 | + struct rkisp_info2ddr info2ddr; |
|---|
| 2597 | 3631 | long ret = 0; |
|---|
| 3632 | + u64 module_id; |
|---|
| 2598 | 3633 | |
|---|
| 2599 | 3634 | if (!up && cmd != RKISP_CMD_FREE_SHARED_BUF) |
|---|
| 2600 | 3635 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 2606 | 3641 | ret = rkisp_ioctl(sd, cmd, &trigger); |
|---|
| 2607 | 3642 | break; |
|---|
| 2608 | 3643 | case RKISP_CMD_GET_SHARED_BUF: |
|---|
| 3644 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3645 | + ret = -ENOIOCTLCMD; |
|---|
| 3646 | + break; |
|---|
| 3647 | + } |
|---|
| 2609 | 3648 | ret = rkisp_ioctl(sd, cmd, &resmem); |
|---|
| 2610 | 3649 | if (!ret && copy_to_user(up, &resmem, sizeof(resmem))) |
|---|
| 2611 | 3650 | ret = -EFAULT; |
|---|
| 2612 | 3651 | break; |
|---|
| 2613 | 3652 | case RKISP_CMD_FREE_SHARED_BUF: |
|---|
| 3653 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3654 | + ret = -ENOIOCTLCMD; |
|---|
| 3655 | + break; |
|---|
| 3656 | + } |
|---|
| 2614 | 3657 | ret = rkisp_ioctl(sd, cmd, NULL); |
|---|
| 2615 | 3658 | break; |
|---|
| 2616 | 3659 | case RKISP_CMD_GET_LDCHBUF_INFO: |
|---|
| .. | .. |
|---|
| 2624 | 3667 | ret = rkisp_ioctl(sd, cmd, &ldchsize); |
|---|
| 2625 | 3668 | break; |
|---|
| 2626 | 3669 | case RKISP_CMD_GET_MESHBUF_INFO: |
|---|
| 2627 | | - if (copy_from_user(&meshsize, up, sizeof(meshsize))) |
|---|
| 3670 | + if (copy_from_user(&meshbuf, up, sizeof(meshbuf))) |
|---|
| 2628 | 3671 | return -EFAULT; |
|---|
| 2629 | 3672 | ret = rkisp_ioctl(sd, cmd, &meshbuf); |
|---|
| 2630 | 3673 | if (!ret && copy_to_user(up, &meshbuf, sizeof(meshbuf))) |
|---|
| .. | .. |
|---|
| 2636 | 3679 | ret = rkisp_ioctl(sd, cmd, &meshsize); |
|---|
| 2637 | 3680 | break; |
|---|
| 2638 | 3681 | case RKISP_CMD_GET_SHM_BUFFD: |
|---|
| 3682 | + if (!IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP)) { |
|---|
| 3683 | + ret = -ENOIOCTLCMD; |
|---|
| 3684 | + break; |
|---|
| 3685 | + } |
|---|
| 2639 | 3686 | if (copy_from_user(&shmem, up, sizeof(shmem))) |
|---|
| 2640 | 3687 | return -EFAULT; |
|---|
| 2641 | 3688 | ret = rkisp_ioctl(sd, cmd, &shmem); |
|---|
| .. | .. |
|---|
| 2646 | 3693 | ret = rkisp_ioctl(sd, cmd, &idxfd); |
|---|
| 2647 | 3694 | if (!ret && copy_to_user(up, &idxfd, sizeof(idxfd))) |
|---|
| 2648 | 3695 | ret = -EFAULT; |
|---|
| 3696 | + break; |
|---|
| 3697 | + case RKISP_CMD_INFO2DDR: |
|---|
| 3698 | + if (copy_from_user(&info2ddr, up, sizeof(info2ddr))) |
|---|
| 3699 | + return -EFAULT; |
|---|
| 3700 | + ret = rkisp_ioctl(sd, cmd, &info2ddr); |
|---|
| 3701 | + if (!ret && copy_to_user(up, &info2ddr, sizeof(info2ddr))) |
|---|
| 3702 | + ret = -EFAULT; |
|---|
| 3703 | + break; |
|---|
| 3704 | + case RKISP_CMD_MESHBUF_FREE: |
|---|
| 3705 | + if (copy_from_user(&module_id, up, sizeof(module_id))) |
|---|
| 3706 | + return -EFAULT; |
|---|
| 3707 | + ret = rkisp_ioctl(sd, cmd, &module_id); |
|---|
| 3708 | + break; |
|---|
| 3709 | + case RKISP_CMD_MULTI_DEV_FORCE_ENUM: |
|---|
| 3710 | + ret = rkisp_ioctl(sd, cmd, NULL); |
|---|
| 2649 | 3711 | break; |
|---|
| 2650 | 3712 | default: |
|---|
| 2651 | 3713 | ret = -ENOIOCTLCMD; |
|---|
| .. | .. |
|---|
| 2673 | 3735 | |
|---|
| 2674 | 3736 | static const struct v4l2_subdev_video_ops rkisp_isp_sd_video_ops = { |
|---|
| 2675 | 3737 | .s_stream = rkisp_isp_sd_s_stream, |
|---|
| 3738 | + .s_rx_buffer = rkisp_sd_s_rx_buffer, |
|---|
| 2676 | 3739 | }; |
|---|
| 2677 | 3740 | |
|---|
| 2678 | 3741 | static const struct v4l2_subdev_core_ops rkisp_isp_core_ops = { |
|---|
| .. | .. |
|---|
| 2699 | 3762 | struct ispsd_in_fmt *in_fmt = &isp_sd->in_fmt; |
|---|
| 2700 | 3763 | struct ispsd_out_fmt *out_fmt = &isp_sd->out_fmt; |
|---|
| 2701 | 3764 | |
|---|
| 2702 | | - *in_fmt = rkisp_isp_input_formats[0]; |
|---|
| 3765 | + *in_fmt = rkisp_isp_input_formats[8]; |
|---|
| 2703 | 3766 | in_frm->width = RKISP_DEFAULT_WIDTH; |
|---|
| 2704 | 3767 | in_frm->height = RKISP_DEFAULT_HEIGHT; |
|---|
| 2705 | 3768 | in_frm->code = in_fmt->mbus_code; |
|---|
| .. | .. |
|---|
| 2723 | 3786 | struct v4l2_subdev *sd = &isp_sdev->sd; |
|---|
| 2724 | 3787 | int ret; |
|---|
| 2725 | 3788 | |
|---|
| 3789 | + mutex_init(&isp_dev->buf_lock); |
|---|
| 3790 | + spin_lock_init(&isp_dev->cmsk_lock); |
|---|
| 2726 | 3791 | spin_lock_init(&isp_dev->rdbk_lock); |
|---|
| 2727 | 3792 | ret = kfifo_alloc(&isp_dev->rdbk_kfifo, |
|---|
| 2728 | 3793 | 16 * sizeof(struct isp2x_csi_trigger), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 2760 | 3825 | rkisp_isp_sd_init_default_fmt(isp_sdev); |
|---|
| 2761 | 3826 | isp_dev->hdr.sensor = NULL; |
|---|
| 2762 | 3827 | isp_dev->isp_state = ISP_STOP; |
|---|
| 2763 | | - |
|---|
| 3828 | + atomic_set(&isp_sdev->frm_sync_seq, 0); |
|---|
| 2764 | 3829 | rkisp_monitor_init(isp_dev); |
|---|
| 3830 | + INIT_WORK(&isp_dev->rdbk_work, rkisp_rdbk_work); |
|---|
| 2765 | 3831 | return 0; |
|---|
| 2766 | 3832 | err_cleanup_media_entity: |
|---|
| 2767 | 3833 | media_entity_cleanup(&sd->entity); |
|---|
| .. | .. |
|---|
| 2802 | 3868 | }) |
|---|
| 2803 | 3869 | |
|---|
| 2804 | 3870 | #ifdef CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP |
|---|
| 3871 | +static void rkisp_save_tb_info(struct rkisp_device *isp_dev) |
|---|
| 3872 | +{ |
|---|
| 3873 | + struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; |
|---|
| 3874 | + void *resmem_va = phys_to_virt(isp_dev->resmem_pa); |
|---|
| 3875 | + struct rkisp_thunderboot_resmem_head *head = resmem_va; |
|---|
| 3876 | + int size = 0, offset = 0; |
|---|
| 3877 | + void *param = NULL; |
|---|
| 3878 | + |
|---|
| 3879 | + switch (isp_dev->isp_ver) { |
|---|
| 3880 | + case ISP_V32: |
|---|
| 3881 | + size = sizeof(struct rkisp32_thunderboot_resmem_head); |
|---|
| 3882 | + offset = size * isp_dev->dev_id; |
|---|
| 3883 | + break; |
|---|
| 3884 | + default: |
|---|
| 3885 | + break; |
|---|
| 3886 | + } |
|---|
| 3887 | + |
|---|
| 3888 | + if (size && size < isp_dev->resmem_size) { |
|---|
| 3889 | + dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr + offset, |
|---|
| 3890 | + size, DMA_FROM_DEVICE); |
|---|
| 3891 | + params_vdev->is_first_cfg = true; |
|---|
| 3892 | + if (isp_dev->isp_ver == ISP_V32) { |
|---|
| 3893 | + struct rkisp32_thunderboot_resmem_head *tmp = resmem_va + offset; |
|---|
| 3894 | + |
|---|
| 3895 | + param = &tmp->cfg; |
|---|
| 3896 | + head = &tmp->head; |
|---|
| 3897 | + v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 3898 | + "tb param module en:0x%llx upd:0x%llx cfg upd:0x%llx\n", |
|---|
| 3899 | + tmp->cfg.module_en_update, |
|---|
| 3900 | + tmp->cfg.module_ens, |
|---|
| 3901 | + tmp->cfg.module_cfg_update); |
|---|
| 3902 | + } |
|---|
| 3903 | + if (param) |
|---|
| 3904 | + params_vdev->ops->save_first_param(params_vdev, param); |
|---|
| 3905 | + } else if (size > isp_dev->resmem_size) { |
|---|
| 3906 | + v4l2_err(&isp_dev->v4l2_dev, |
|---|
| 3907 | + "resmem size:%zu no enough for head:%d\n", |
|---|
| 3908 | + isp_dev->resmem_size, size); |
|---|
| 3909 | + head->complete = RKISP_TB_NG; |
|---|
| 3910 | + } |
|---|
| 3911 | + memcpy(&isp_dev->tb_head, head, sizeof(*head)); |
|---|
| 3912 | +} |
|---|
| 3913 | + |
|---|
| 2805 | 3914 | void rkisp_chk_tb_over(struct rkisp_device *isp_dev) |
|---|
| 2806 | 3915 | { |
|---|
| 3916 | + struct rkisp_isp_params_vdev *params_vdev = &isp_dev->params_vdev; |
|---|
| 3917 | + struct rkisp_hw_dev *hw = isp_dev->hw_dev; |
|---|
| 2807 | 3918 | struct rkisp_thunderboot_resmem_head *head; |
|---|
| 2808 | 3919 | enum rkisp_tb_state tb_state; |
|---|
| 2809 | 3920 | void *resmem_va; |
|---|
| 2810 | 3921 | |
|---|
| 2811 | | - if (!isp_dev->hw_dev->is_thunderboot) |
|---|
| 3922 | + if (!isp_dev->is_thunderboot) |
|---|
| 2812 | 3923 | return; |
|---|
| 2813 | 3924 | |
|---|
| 2814 | | - if (!atomic_read(&isp_dev->hw_dev->tb_ref)) { |
|---|
| 2815 | | - rkisp_tb_set_state(RKISP_TB_NG); |
|---|
| 2816 | | - rkisp_tb_unprotect_clk(); |
|---|
| 2817 | | - rkisp_register_irq(isp_dev->hw_dev); |
|---|
| 2818 | | - isp_dev->hw_dev->is_thunderboot = false; |
|---|
| 2819 | | - return; |
|---|
| 2820 | | - } |
|---|
| 3925 | + if (isp_dev->isp_ver == ISP_V32 && params_vdev->is_first_cfg) |
|---|
| 3926 | + goto end; |
|---|
| 2821 | 3927 | |
|---|
| 2822 | 3928 | resmem_va = phys_to_virt(isp_dev->resmem_pa); |
|---|
| 2823 | 3929 | head = (struct rkisp_thunderboot_resmem_head *)resmem_va; |
|---|
| 2824 | | - if (isp_dev->is_thunderboot) { |
|---|
| 2825 | | - shm_head_poll_timeout(isp_dev, !!head->enable, 2000, 200 * USEC_PER_MSEC); |
|---|
| 2826 | | - shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 600 * USEC_PER_MSEC); |
|---|
| 2827 | | - if (head->complete != RKISP_TB_OK) |
|---|
| 2828 | | - v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 2829 | | - "wait thunderboot over timeout\n"); |
|---|
| 3930 | + dma_sync_single_for_cpu(isp_dev->dev, isp_dev->resmem_addr, |
|---|
| 3931 | + sizeof(struct rkisp_thunderboot_resmem_head), |
|---|
| 3932 | + DMA_FROM_DEVICE); |
|---|
| 2830 | 3933 | |
|---|
| 2831 | | - v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 2832 | | - "thunderboot info: %d, %d, %d, %d, %d, %d, 0x%x\n", |
|---|
| 2833 | | - head->enable, |
|---|
| 2834 | | - head->complete, |
|---|
| 2835 | | - head->frm_total, |
|---|
| 2836 | | - head->hdr_mode, |
|---|
| 2837 | | - head->width, |
|---|
| 2838 | | - head->height, |
|---|
| 2839 | | - head->bus_fmt); |
|---|
| 3934 | + shm_head_poll_timeout(isp_dev, !!head->complete, 5000, 400 * USEC_PER_MSEC); |
|---|
| 3935 | + if (head->complete != RKISP_TB_OK) { |
|---|
| 3936 | + v4l2_err(&isp_dev->v4l2_dev, "wait thunderboot over timeout\n"); |
|---|
| 3937 | + } else { |
|---|
| 3938 | + int i, timeout = 50; |
|---|
| 2840 | 3939 | |
|---|
| 2841 | | - tb_state = RKISP_TB_OK; |
|---|
| 2842 | | - if (head->complete != RKISP_TB_OK) { |
|---|
| 2843 | | - head->frm_total = 0; |
|---|
| 2844 | | - tb_state = RKISP_TB_NG; |
|---|
| 3940 | + /* wait for all isp dev to register */ |
|---|
| 3941 | + if (head->camera_num > 1) { |
|---|
| 3942 | + while (timeout--) { |
|---|
| 3943 | + if (hw->dev_num >= head->camera_num && |
|---|
| 3944 | + hw->isp[hw->dev_num - 1]->is_probe_end) |
|---|
| 3945 | + break; |
|---|
| 3946 | + usleep_range(200, 210); |
|---|
| 3947 | + } |
|---|
| 3948 | + if (head->camera_num > hw->dev_num) { |
|---|
| 3949 | + v4l2_err(&isp_dev->v4l2_dev, |
|---|
| 3950 | + "thunderboot invalid camera num:%d, dev num:%d\n", |
|---|
| 3951 | + head->camera_num, hw->dev_num); |
|---|
| 3952 | + goto end; |
|---|
| 3953 | + } |
|---|
| 2845 | 3954 | } |
|---|
| 3955 | + for (i = 0; i < head->camera_num; i++) |
|---|
| 3956 | + rkisp_save_tb_info(hw->isp[i]); |
|---|
| 3957 | + } |
|---|
| 3958 | +end: |
|---|
| 3959 | + head = &isp_dev->tb_head; |
|---|
| 3960 | + v4l2_info(&isp_dev->v4l2_dev, |
|---|
| 3961 | + "thunderboot info: %d, %d, %d, %d, %d, %d | %d %d\n", |
|---|
| 3962 | + head->enable, |
|---|
| 3963 | + head->complete, |
|---|
| 3964 | + head->frm_total, |
|---|
| 3965 | + head->hdr_mode, |
|---|
| 3966 | + head->width, |
|---|
| 3967 | + head->height, |
|---|
| 3968 | + head->camera_num, |
|---|
| 3969 | + head->camera_index); |
|---|
| 3970 | + |
|---|
| 3971 | + tb_state = RKISP_TB_OK; |
|---|
| 3972 | + if (head->complete != RKISP_TB_OK) { |
|---|
| 3973 | + head->frm_total = 0; |
|---|
| 3974 | + tb_state = RKISP_TB_NG; |
|---|
| 3975 | + } |
|---|
| 3976 | + |
|---|
| 3977 | + if (hw->is_thunderboot) { |
|---|
| 3978 | + rkisp_register_irq(hw); |
|---|
| 2846 | 3979 | rkisp_tb_set_state(tb_state); |
|---|
| 2847 | 3980 | rkisp_tb_unprotect_clk(); |
|---|
| 2848 | | - rkisp_register_irq(isp_dev->hw_dev); |
|---|
| 2849 | | - pm_runtime_put(isp_dev->hw_dev->dev); |
|---|
| 2850 | | - isp_dev->hw_dev->is_thunderboot = false; |
|---|
| 2851 | | - isp_dev->is_thunderboot = false; |
|---|
| 2852 | | - atomic_dec(&isp_dev->hw_dev->tb_ref); |
|---|
| 3981 | + hw->is_thunderboot = false; |
|---|
| 2853 | 3982 | } |
|---|
| 3983 | + isp_dev->is_thunderboot = false; |
|---|
| 2854 | 3984 | } |
|---|
| 2855 | 3985 | #endif |
|---|
| 2856 | 3986 | |
|---|
| .. | .. |
|---|
| 2958 | 4088 | unsigned int isp3a_mis, |
|---|
| 2959 | 4089 | struct rkisp_device *dev) |
|---|
| 2960 | 4090 | { |
|---|
| 2961 | | - void __iomem *base = dev->base_addr; |
|---|
| 4091 | + struct rkisp_hw_dev *hw = dev->hw_dev; |
|---|
| 4092 | + void __iomem *base = hw->unite != ISP_UNITE_TWO ? |
|---|
| 4093 | + hw->base_addr : hw->base_next_addr; |
|---|
| 2962 | 4094 | unsigned int isp_mis_tmp = 0; |
|---|
| 2963 | 4095 | unsigned int isp_err = 0; |
|---|
| 2964 | 4096 | u32 si3a_isr_mask = ISP2X_SIAWB_DONE | ISP2X_SIAF_FIN | |
|---|
| .. | .. |
|---|
| 2968 | 4100 | ISP2X_3A_RAWHIST_BIG | ISP2X_3A_RAWHIST_CH0 | |
|---|
| 2969 | 4101 | ISP2X_3A_RAWHIST_CH1 | ISP2X_3A_RAWHIST_CH2 | |
|---|
| 2970 | 4102 | ISP2X_3A_RAWAF_SUM | ISP2X_3A_RAWAF_LUM | |
|---|
| 2971 | | - ISP2X_3A_RAWAF | ISP2X_3A_RAWAWB; |
|---|
| 4103 | + ISP2X_3A_RAWAWB; |
|---|
| 2972 | 4104 | bool sof_event_later = false; |
|---|
| 2973 | 4105 | |
|---|
| 2974 | 4106 | /* |
|---|
| .. | .. |
|---|
| 2978 | 4110 | if (isp3a_mis & ISP2X_3A_RAWAE_BIG && dev->params_vdev.rdbk_times > 0) |
|---|
| 2979 | 4111 | writel(BIT(31), base + RAWAE_BIG1_BASE + RAWAE_BIG_CTRL); |
|---|
| 2980 | 4112 | |
|---|
| 4113 | + if (hw->unite == ISP_UNITE_TWO) { |
|---|
| 4114 | + u32 val = rkisp_read(dev, ISP3X_ISP_RIS, true); |
|---|
| 4115 | + |
|---|
| 4116 | + if (val) { |
|---|
| 4117 | + rkisp_write(dev, ISP3X_ISP_ICR, val, true); |
|---|
| 4118 | + v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, |
|---|
| 4119 | + "left isp isr:0x%x\n", val); |
|---|
| 4120 | + if (isp_mis & CIF_ISP_FRAME && !(val & CIF_ISP_FRAME)) { |
|---|
| 4121 | + /* wait isp0 frame end */ |
|---|
| 4122 | + int timeout = read_poll_timeout_atomic(rkisp_read, |
|---|
| 4123 | + val, val & CIF_ISP_FRAME, 20, 20 * 50, true, dev, ISP3X_ISP_RIS, true); |
|---|
| 4124 | + |
|---|
| 4125 | + if (val) |
|---|
| 4126 | + rkisp_write(dev, ISP3X_ISP_ICR, val, true); |
|---|
| 4127 | + if (timeout) |
|---|
| 4128 | + dev_err(dev->dev, "wait isp end timeout\n"); |
|---|
| 4129 | + } |
|---|
| 4130 | + } |
|---|
| 4131 | + } |
|---|
| 2981 | 4132 | v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, |
|---|
| 2982 | 4133 | "isp isr:0x%x, 0x%x\n", isp_mis, isp3a_mis); |
|---|
| 2983 | 4134 | dev->isp_isr_cnt++; |
|---|
| 2984 | 4135 | /* start edge of v_sync */ |
|---|
| 2985 | 4136 | if (isp_mis & CIF_ISP_V_START) { |
|---|
| 2986 | | - if (dev->isp_state & ISP_FRAME_END) { |
|---|
| 2987 | | - u64 tmp = dev->isp_sdev.dbg.interval + |
|---|
| 2988 | | - dev->isp_sdev.dbg.timestamp; |
|---|
| 2989 | | - |
|---|
| 2990 | | - dev->isp_sdev.dbg.timestamp = ktime_get_ns(); |
|---|
| 2991 | | - /* v-blank: frame_end - frame_start */ |
|---|
| 2992 | | - dev->isp_sdev.dbg.delay = dev->isp_sdev.dbg.timestamp - tmp; |
|---|
| 2993 | | - } |
|---|
| 2994 | | - rkisp_set_state(&dev->isp_state, ISP_FRAME_VS); |
|---|
| 2995 | 4137 | if (dev->hw_dev->monitor.is_en) { |
|---|
| 2996 | 4138 | rkisp_set_state(&dev->hw_dev->monitor.state, ISP_FRAME_VS); |
|---|
| 2997 | 4139 | if (!completion_done(&dev->hw_dev->monitor.cmpl)) |
|---|
| 2998 | 4140 | complete(&dev->hw_dev->monitor.cmpl); |
|---|
| 2999 | 4141 | } |
|---|
| 3000 | | - /* last vsync to config next buf */ |
|---|
| 3001 | | - if (!dev->filt_state[RDBK_F_VS]) |
|---|
| 3002 | | - rkisp_bridge_update_mi(dev, isp_mis); |
|---|
| 3003 | | - else |
|---|
| 3004 | | - dev->filt_state[RDBK_F_VS]--; |
|---|
| 4142 | + |
|---|
| 3005 | 4143 | if (IS_HDR_RDBK(dev->hdr.op_mode)) { |
|---|
| 3006 | | - /* read 3d lut at isp readback */ |
|---|
| 3007 | | - if (!dev->hw_dev->is_single) |
|---|
| 3008 | | - rkisp_write(dev, ISP_3DLUT_UPDATE, 0, true); |
|---|
| 4144 | + /* disabled frame end to read 3dlut for multi sensor |
|---|
| 4145 | + * 3dlut will update at isp readback |
|---|
| 4146 | + */ |
|---|
| 4147 | + if (!dev->hw_dev->is_single) { |
|---|
| 4148 | + writel(0, hw->base_addr + ISP_3DLUT_UPDATE); |
|---|
| 4149 | + if (hw->unite == ISP_UNITE_TWO) |
|---|
| 4150 | + writel(0, hw->base_next_addr + ISP_3DLUT_UPDATE); |
|---|
| 4151 | + } |
|---|
| 3009 | 4152 | rkisp_stats_rdbk_enable(&dev->stats_vdev, true); |
|---|
| 3010 | 4153 | goto vs_skip; |
|---|
| 3011 | 4154 | } |
|---|
| 3012 | 4155 | if (dev->cap_dev.stream[RKISP_STREAM_SP].interlaced) { |
|---|
| 3013 | 4156 | /* 0 = ODD 1 = EVEN */ |
|---|
| 3014 | | - if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2) { |
|---|
| 4157 | + if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) { |
|---|
| 3015 | 4158 | void __iomem *addr = NULL; |
|---|
| 3016 | 4159 | |
|---|
| 3017 | 4160 | if (dev->isp_ver == ISP_V10 || |
|---|
| .. | .. |
|---|
| 3035 | 4178 | if (dev->vs_irq < 0 && !sof_event_later) { |
|---|
| 3036 | 4179 | dev->isp_sdev.frm_timestamp = ktime_get_ns(); |
|---|
| 3037 | 4180 | rkisp_isp_queue_event_sof(&dev->isp_sdev); |
|---|
| 4181 | + rkisp_stream_frame_start(dev, isp_mis); |
|---|
| 3038 | 4182 | } |
|---|
| 3039 | 4183 | vs_skip: |
|---|
| 3040 | 4184 | writel(CIF_ISP_V_START, base + CIF_ISP_ICR); |
|---|
| .. | .. |
|---|
| 3078 | 4222 | } |
|---|
| 3079 | 4223 | } |
|---|
| 3080 | 4224 | |
|---|
| 4225 | + if (isp3a_mis & ISP2X_3A_RAWAF) { |
|---|
| 4226 | + writel(ISP3X_3A_RAWAF, base + ISP3X_ISP_3A_ICR); |
|---|
| 4227 | + /* 3a irq will with lsc_lut_err irq if isp version below isp32 */ |
|---|
| 4228 | + if (isp_mis & ISP2X_LSC_LUT_ERR) |
|---|
| 4229 | + isp_mis &= ~ISP2X_LSC_LUT_ERR; |
|---|
| 4230 | + if (dev->rawaf_irq_cnt == 0) |
|---|
| 4231 | + rkisp_stream_buf_done_early(dev); |
|---|
| 4232 | + dev->rawaf_irq_cnt++; |
|---|
| 4233 | + } |
|---|
| 4234 | + |
|---|
| 3081 | 4235 | if (isp_mis & ISP2X_LSC_LUT_ERR) { |
|---|
| 3082 | 4236 | writel(ISP2X_LSC_LUT_ERR, base + CIF_ISP_ICR); |
|---|
| 3083 | 4237 | |
|---|
| .. | .. |
|---|
| 3089 | 4243 | |
|---|
| 3090 | 4244 | /* sampled input frame is complete */ |
|---|
| 3091 | 4245 | if (isp_mis & CIF_ISP_FRAME_IN) { |
|---|
| 4246 | + dev->isp_sdev.dbg.interval = |
|---|
| 4247 | + ktime_get_ns() - dev->isp_sdev.dbg.timestamp; |
|---|
| 3092 | 4248 | rkisp_set_state(&dev->isp_state, ISP_FRAME_IN); |
|---|
| 3093 | 4249 | writel(CIF_ISP_FRAME_IN, base + CIF_ISP_ICR); |
|---|
| 3094 | 4250 | isp_mis_tmp = readl(base + CIF_ISP_MIS); |
|---|
| 3095 | 4251 | if (isp_mis_tmp & CIF_ISP_FRAME_IN) |
|---|
| 3096 | 4252 | v4l2_err(&dev->v4l2_dev, "isp icr frame_in err: 0x%x\n", |
|---|
| 3097 | 4253 | isp_mis_tmp); |
|---|
| 3098 | | - |
|---|
| 3099 | | - dev->isp_err_cnt = 0; |
|---|
| 3100 | | - dev->isp_state &= ~ISP_ERROR; |
|---|
| 3101 | 4254 | } |
|---|
| 3102 | 4255 | |
|---|
| 3103 | 4256 | /* frame was completely put out */ |
|---|
| 3104 | 4257 | if (isp_mis & CIF_ISP_FRAME) { |
|---|
| 3105 | | - dev->isp_sdev.dbg.interval = |
|---|
| 3106 | | - ktime_get_ns() - dev->isp_sdev.dbg.timestamp; |
|---|
| 4258 | + dev->rawaf_irq_cnt = 0; |
|---|
| 4259 | + if (!dev->is_pre_on || !IS_HDR_RDBK(dev->rd_mode)) |
|---|
| 4260 | + dev->isp_sdev.dbg.interval = |
|---|
| 4261 | + ktime_get_ns() - dev->isp_sdev.dbg.timestamp; |
|---|
| 3107 | 4262 | /* Clear Frame In (ISP) */ |
|---|
| 3108 | 4263 | rkisp_set_state(&dev->isp_state, ISP_FRAME_END); |
|---|
| 3109 | 4264 | writel(CIF_ISP_FRAME, base + CIF_ISP_ICR); |
|---|
| .. | .. |
|---|
| 3113 | 4268 | "isp icr frame end err: 0x%x\n", isp_mis_tmp); |
|---|
| 3114 | 4269 | rkisp_dmarx_get_frame(dev, &dev->isp_sdev.dbg.id, NULL, NULL, true); |
|---|
| 3115 | 4270 | rkisp_isp_read_add_fifo_data(dev); |
|---|
| 4271 | + |
|---|
| 4272 | + dev->isp_err_cnt = 0; |
|---|
| 4273 | + dev->isp_state &= ~ISP_ERROR; |
|---|
| 4274 | + } |
|---|
| 4275 | + |
|---|
| 4276 | + if (isp_mis & CIF_ISP_V_START) { |
|---|
| 4277 | + if (dev->isp_state & ISP_FRAME_END) { |
|---|
| 4278 | + u64 tmp = dev->isp_sdev.dbg.interval + |
|---|
| 4279 | + dev->isp_sdev.dbg.timestamp; |
|---|
| 4280 | + |
|---|
| 4281 | + dev->isp_sdev.dbg.timestamp = ktime_get_ns(); |
|---|
| 4282 | + /* v-blank: frame(N)start - frame(N-1)end */ |
|---|
| 4283 | + dev->isp_sdev.dbg.delay = dev->isp_sdev.dbg.timestamp - tmp; |
|---|
| 4284 | + } |
|---|
| 4285 | + rkisp_set_state(&dev->isp_state, ISP_FRAME_VS); |
|---|
| 4286 | + if (dev->procfs.is_fs_wait) { |
|---|
| 4287 | + dev->procfs.is_fs_wait = false; |
|---|
| 4288 | + wake_up(&dev->procfs.fs_wait); |
|---|
| 4289 | + } |
|---|
| 3116 | 4290 | } |
|---|
| 3117 | 4291 | |
|---|
| 3118 | 4292 | if ((isp_mis & (CIF_ISP_FRAME | si3a_isr_mask)) || |
|---|
| .. | .. |
|---|
| 3129 | 4303 | |
|---|
| 3130 | 4304 | if ((isp_mis & CIF_ISP_FRAME) && dev->stats_vdev.rdbk_mode) |
|---|
| 3131 | 4305 | rkisp_stats_rdbk_enable(&dev->stats_vdev, false); |
|---|
| 4306 | + |
|---|
| 4307 | + if (!IS_HDR_RDBK(dev->hdr.op_mode)) |
|---|
| 4308 | + rkisp_config_cmsk(dev); |
|---|
| 4309 | + } |
|---|
| 4310 | + |
|---|
| 4311 | + if (isp_mis & CIF_ISP_FRAME) { |
|---|
| 4312 | + if (dev->hw_dev->isp_ver == ISP_V32) { |
|---|
| 4313 | + struct rkisp_stream *s = &dev->cap_dev.stream[RKISP_STREAM_LUMA]; |
|---|
| 4314 | + |
|---|
| 4315 | + s->ops->frame_end(s, FRAME_IRQ); |
|---|
| 4316 | + } |
|---|
| 4317 | + if (dev->procfs.is_fe_wait) { |
|---|
| 4318 | + dev->procfs.is_fe_wait = false; |
|---|
| 4319 | + wake_up(&dev->procfs.fe_wait); |
|---|
| 4320 | + } |
|---|
| 3132 | 4321 | } |
|---|
| 3133 | 4322 | |
|---|
| 3134 | 4323 | /* |
|---|
| .. | .. |
|---|
| 3136 | 4325 | * lot of register writes. Do those only one per frame. |
|---|
| 3137 | 4326 | * Do the updates in the order of the processing flow. |
|---|
| 3138 | 4327 | */ |
|---|
| 3139 | | - rkisp_params_isr(&dev->params_vdev, isp_mis); |
|---|
| 4328 | + if (isp_mis & (CIF_ISP_V_START | CIF_ISP_FRAME)) |
|---|
| 4329 | + rkisp_params_isr(&dev->params_vdev, isp_mis); |
|---|
| 3140 | 4330 | |
|---|
| 3141 | 4331 | /* cur frame end and next frame start irq togeter */ |
|---|
| 3142 | 4332 | if (dev->vs_irq < 0 && sof_event_later) { |
|---|
| 3143 | 4333 | dev->isp_sdev.frm_timestamp = ktime_get_ns(); |
|---|
| 3144 | 4334 | rkisp_isp_queue_event_sof(&dev->isp_sdev); |
|---|
| 4335 | + rkisp_stream_frame_start(dev, isp_mis); |
|---|
| 3145 | 4336 | } |
|---|
| 3146 | 4337 | |
|---|
| 3147 | | - if (isp_mis & CIF_ISP_FRAME_IN) |
|---|
| 3148 | | - rkisp_check_idle(dev, ISP_FRAME_IN); |
|---|
| 4338 | + if (isp_mis & ISP3X_OUT_FRM_QUARTER) { |
|---|
| 4339 | + writel(ISP3X_OUT_FRM_QUARTER, base + CIF_ISP_ICR); |
|---|
| 4340 | + rkisp_dvbm_event(dev, ISP3X_OUT_FRM_QUARTER); |
|---|
| 4341 | + } |
|---|
| 4342 | + if (isp_mis & ISP3X_OUT_FRM_HALF) { |
|---|
| 4343 | + writel(ISP3X_OUT_FRM_HALF, base + CIF_ISP_ICR); |
|---|
| 4344 | + rkisp_dvbm_event(dev, ISP3X_OUT_FRM_HALF); |
|---|
| 4345 | + rkisp_stream_buf_done_early(dev); |
|---|
| 4346 | + } |
|---|
| 4347 | + if (isp_mis & ISP3X_OUT_FRM_END) { |
|---|
| 4348 | + writel(ISP3X_OUT_FRM_END, base + CIF_ISP_ICR); |
|---|
| 4349 | + rkisp_dvbm_event(dev, ISP3X_OUT_FRM_END); |
|---|
| 4350 | + } |
|---|
| 4351 | + |
|---|
| 3149 | 4352 | if (isp_mis & CIF_ISP_FRAME) |
|---|
| 3150 | 4353 | rkisp_check_idle(dev, ISP_FRAME_END); |
|---|
| 3151 | 4354 | } |
|---|