forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-09 244b2c5ca8b14627e4a17755e5922221e121c771
kernel/drivers/video/rockchip/vehicle/vehicle_cif.c
....@@ -37,7 +37,6 @@
3737 #include <media/v4l2-mediabus.h>
3838 #include <linux/delay.h>
3939 #include <linux/pm_runtime.h>
40
-#include <dt-bindings/soc/rockchip-system-status.h>
4140 #include <soc/rockchip/rockchip-system-status.h>
4241 #include <linux/phy/phy.h>
4342 #include <linux/uaccess.h>
....@@ -2266,6 +2265,31 @@
22662265 return index;
22672266 }
22682267
2268
+static enum cif_reg_index get_reg_index_of_frm_num(int channel_id)
2269
+{
2270
+ enum cif_reg_index index;
2271
+
2272
+ switch (channel_id) {
2273
+ case 0:
2274
+ index = CIF_REG_MIPI_FRAME_NUM_VC0;
2275
+ break;
2276
+ case 1:
2277
+ index = CIF_REG_MIPI_FRAME_NUM_VC1;
2278
+ break;
2279
+ case 2:
2280
+ index = CIF_REG_MIPI_FRAME_NUM_VC2;
2281
+ break;
2282
+ case 3:
2283
+ index = CIF_REG_MIPI_FRAME_NUM_VC3;
2284
+ break;
2285
+ default:
2286
+ index = CIF_REG_MIPI_FRAME_NUM_VC0;
2287
+ break;
2288
+ }
2289
+
2290
+ return index;
2291
+}
2292
+
22692293 static enum cif_reg_index get_reg_index_of_frm1_y_addr(int channel_id)
22702294 {
22712295 enum cif_reg_index index;
....@@ -2758,14 +2782,14 @@
27582782 VEHICLE_DG("%s, LINE=%d, channel->fmt_val = 0x%x", __func__, __LINE__, channel->fmt_val);
27592783 if (cfg->input_format == CIF_INPUT_FORMAT_PAL ||
27602784 cfg->input_format == CIF_INPUT_FORMAT_NTSC) {
2761
- VEHICLE_DG("CVBS IN PAL or NTSC config.");
2785
+ VEHICLE_INFO("CVBS IN PAL or NTSC config.");
27622786 channel->virtual_width *= 2;
27632787 cif->interlaced_enable = true;
27642788 cif->interlaced_offset = channel->width;
27652789 cif->interlaced_counts = 0;
27662790 cif->interlaced_buffer = 0;
27672791 channel->height /= 2;
2768
- VEHICLE_DG("do denterlaced.\n");
2792
+ VEHICLE_INFO("do denterlaced.\n");
27692793 }
27702794
27712795 channel->data_type = get_data_type(cfg->mbus_code,
....@@ -3930,7 +3954,7 @@
39303954 static unsigned long temp_y_addr, temp_uv_addr;
39313955 int commit_buf = 0;
39323956 struct vehicle_rkcif_dummy_buffer *dummy_buf = &cif->dummy_buf;
3933
-
3957
+ u32 frm_num_reg, frame_id = 0;
39343958 VEHICLE_DG("@%s, enter, mipi_id(%d)\n", __func__, mipi_id);
39353959
39363960 if ((frame_ready > 1) || (cif->cif_cfg.buf_num < 2) ||
....@@ -3946,6 +3970,10 @@
39463970 frm0_addr_uv = get_reg_index_of_frm0_uv_addr(mipi_id);
39473971 frm1_addr_y = get_reg_index_of_frm1_y_addr(mipi_id);
39483972 frm1_addr_uv = get_reg_index_of_frm1_uv_addr(mipi_id);
3973
+ frm_num_reg = get_reg_index_of_frm_num(mipi_id);
3974
+ frame_id = rkcif_read_reg(cif, frm_num_reg);
3975
+ VEHICLE_DG("@%s, frm_num_reg(0x%x), frame_id:0x%x\n", __func__,
3976
+ frm_num_reg, frame_id);
39493977 } else {
39503978 frm0_addr_y = get_dvp_reg_index_of_frm0_y_addr(mipi_id);
39513979 frm0_addr_uv = get_dvp_reg_index_of_frm0_uv_addr(mipi_id);
....@@ -3979,10 +4007,11 @@
39794007 uv_addr = temp_uv_addr;
39804008 commit_buf = 0;
39814009 } else {
3982
- if ((cif->interlaced_counts % 2) == 0) {
4010
+ if ((frame_id != 0 && (frame_id & 0xffff) % 2 == 0) ||
4011
+ (frame_id == 0 && (cif->interlaced_counts % 2 == 0))) {
39834012 temp_y_addr = vehicle_flinger_request_cif_buffer();
39844013 if (temp_y_addr == 0) {
3985
- VEHICLE_INFO("%s,warnning request buffer failed\n", __func__);
4014
+ VEHICLE_DGERR("%s,warnning request buffer failed\n", __func__);
39864015 spin_unlock(&cif->vbq_lock);
39874016 return -1;
39884017 }
....@@ -3995,6 +4024,11 @@
39954024 //uv_addr = temp_uv_addr;
39964025 uv_addr = temp_uv_addr + cif->interlaced_offset;
39974026 commit_buf = 0; //even & odd field add
4027
+ if (temp_y_addr == 0) {
4028
+ VEHICLE_DGERR("%s,warnning temp_y_addr is NULL!\n", __func__);
4029
+ spin_unlock(&cif->vbq_lock);
4030
+ return -1;
4031
+ }
39984032 }
39994033 WARN_ON(y_addr == cif->interlaced_offset);
40004034 WARN_ON(uv_addr == cif->interlaced_offset);
....@@ -4453,6 +4487,37 @@
44534487 return IRQ_HANDLED;
44544488 }
44554489
4490
+#define vehicle_csi2_err_strncat(dst_str, src_str) {\
4491
+ if (strlen(dst_str) + strlen(src_str) < CSI_ERRSTR_LEN)\
4492
+ strncat(dst_str, src_str, strlen(src_str)); }
4493
+
4494
+static void vehicle_csi2_find_err_vc(int val, char *vc_info)
4495
+{
4496
+ int i;
4497
+ char cur_str[CSI_VCINFO_LEN] = {0};
4498
+
4499
+ memset(vc_info, 0, sizeof(*vc_info));
4500
+ for (i = 0; i < 4; i++) {
4501
+ if ((val >> i) & 0x1) {
4502
+ snprintf(cur_str, CSI_VCINFO_LEN, " %d", i);
4503
+ if (strlen(vc_info) + strlen(cur_str) < CSI_VCINFO_LEN)
4504
+ strncat(vc_info, cur_str, strlen(cur_str));
4505
+ }
4506
+ }
4507
+}
4508
+
4509
+static void vehicle_csi2_err_print_work(struct work_struct *work)
4510
+{
4511
+ struct vehicle_csi2_err_state_work *err_state = container_of(work,
4512
+ struct vehicle_csi2_err_state_work,
4513
+ work);
4514
+
4515
+ pr_err("mipi_csi2: ERR%d:0x%x %s\n", err_state->err_num,
4516
+ err_state->err_val, err_state->err_str);
4517
+ if (err_state->err_num == 1)
4518
+ pr_info("mipi_csi2: err_stat:0x%x\n", err_state->err_stat);
4519
+}
4520
+
44564521 static irqreturn_t vehicle_csirx_irq1(int irq, void *data)
44574522 {
44584523 struct vehicle_cif *cif = (struct vehicle_cif *)data;
....@@ -4460,6 +4525,9 @@
44604525 struct csi2_err_stats *err_list = NULL;
44614526 unsigned long err_stat = 0;
44624527 u32 val;
4528
+ char err_str[CSI_ERRSTR_LEN] = {0};
4529
+ char cur_str[CSI_ERRSTR_LEN] = {0};
4530
+ char vc_info[CSI_VCINFO_LEN] = {0};
44634531
44644532 val = read_reg(hw->csi2_base, CSIHOST_ERR1);
44654533 if (val) {
....@@ -4469,53 +4537,69 @@
44694537 if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
44704538 err_list = &hw->err_list[RK_CSI2_ERR_SOTSYN];
44714539 err_list->cnt++;
4472
- VEHICLE_DGERR(
4473
- "ERR1: start of transmission error, reg: 0x%x,cnt:%d\n",
4474
- val, err_list->cnt);
4540
+
4541
+ vehicle_csi2_find_err_vc(val & 0xf, vc_info);
4542
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot sync,lane:%s) ", vc_info);
4543
+ vehicle_csi2_err_strncat(err_str, cur_str);
44754544 }
44764545
44774546 if (val & CSIHOST_ERR1_ERR_BNDRY_MATCH) {
44784547 err_list = &hw->err_list[RK_CSI2_ERR_FS_FE_MIS];
44794548 err_list->cnt++;
4480
- VEHICLE_DGERR(
4481
- "ERR1: error matching frame start with frame end, reg: 0x%x,cnt:%d\n",
4482
- val, err_list->cnt);
4549
+ vehicle_csi2_find_err_vc((val >> 4) & 0xf, vc_info);
4550
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(fs/fe miss,vc:%s) ", vc_info);
4551
+ vehicle_csi2_err_strncat(err_str, cur_str);
4552
+
44834553 }
44844554
44854555 if (val & CSIHOST_ERR1_ERR_SEQ) {
44864556 err_list = &hw->err_list[RK_CSI2_ERR_FRM_SEQ_ERR];
44874557 err_list->cnt++;
4488
- VEHICLE_DGERR("ERR1: incorrect frame sequence detected, reg: 0x%x,cnt:%d\n",
4489
- val, err_list->cnt);
4558
+ vehicle_csi2_find_err_vc((val >> 8) & 0xf, vc_info);
4559
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(f_seq,vc:%s) ", vc_info);
4560
+ vehicle_csi2_err_strncat(err_str, cur_str);
4561
+
44904562 }
44914563
44924564 if (val & CSIHOST_ERR1_ERR_FRM_DATA) {
44934565 err_list = &hw->err_list[RK_CSI2_ERR_CRC_ONCE];
44944566 err_list->cnt++;
4495
- VEHICLE_DGERR("ERR1: at least one crc error, reg: 0x%x\n,cnt:%d",
4496
- val, err_list->cnt);
4567
+ vehicle_csi2_find_err_vc((val >> 12) & 0xf, vc_info);
4568
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err_data,vc:%s) ", vc_info);
4569
+ vehicle_csi2_err_strncat(err_str, cur_str);
4570
+
44974571 }
44984572
44994573 if (val & CSIHOST_ERR1_ERR_CRC) {
45004574 err_list = &hw->err_list[RK_CSI2_ERR_CRC];
45014575 err_list->cnt++;
4502
- VEHICLE_DGERR("ERR1: crc errors, reg: 0x%x, cnt:%d\n",
4503
- val, err_list->cnt);
4576
+ vehicle_csi2_find_err_vc((val >> 24) & 0xf, vc_info);
4577
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(crc,vc:%s) ", vc_info);
4578
+ vehicle_csi2_err_strncat(err_str, cur_str);
4579
+
45044580 }
45054581
45064582 if (val & CSIHOST_ERR1_ERR_ECC2) {
45074583 err_list = &hw->err_list[RK_CSI2_ERR_CRC];
45084584 err_list->cnt++;
4509
- VEHICLE_DGERR("ERR1: ecc errors, reg: 0x%x, cnt:%d\n",
4510
- val, err_list->cnt);
4511
- }
4512
- if (val & CSIHOST_ERR1_ERR_CTRL)
4513
- VEHICLE_DGERR("ERR1: ctrl errors, reg: 0x%x\n", val);
4585
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc2) ");
4586
+ vehicle_csi2_err_strncat(err_str, cur_str);
45144587
4588
+ }
4589
+ if (val & CSIHOST_ERR1_ERR_CTRL) {
4590
+ vehicle_csi2_find_err_vc((val >> 16) & 0xf, vc_info);
4591
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ctrl,vc:%s) ", vc_info);
4592
+ vehicle_csi2_err_strncat(err_str, cur_str);
4593
+ }
45154594 hw->err_list[RK_CSI2_ERR_ALL].cnt++;
45164595 err_stat = ((hw->err_list[RK_CSI2_ERR_FS_FE_MIS].cnt & 0xff) << 8) |
45174596 ((hw->err_list[RK_CSI2_ERR_ALL].cnt) & 0xff);
4518
- VEHICLE_INFO("%s: err_stat: %x\n", err_stat);
4597
+
4598
+ cif->err_state.err_val = val;
4599
+ cif->err_state.err_num = 1;
4600
+ cif->err_state.err_stat = err_stat;
4601
+ strscpy(cif->err_state.err_str, err_str, CSI_ERRSTR_LEN);
4602
+ queue_work(cif->err_state.err_print_wq, &cif->err_state.work);
45194603
45204604 }
45214605
....@@ -4527,22 +4611,41 @@
45274611 struct vehicle_cif *cif = (struct vehicle_cif *)data;
45284612 struct csi2_dphy_hw *hw = cif->dphy_hw;
45294613 u32 val;
4614
+ char cur_str[CSI_ERRSTR_LEN] = {0};
4615
+ char err_str[CSI_ERRSTR_LEN] = {0};
4616
+ char vc_info[CSI_VCINFO_LEN] = {0};
45304617
45314618 val = read_reg(hw->csi2_base, CSIHOST_ERR2);
45324619 if (val) {
4533
- if (val & CSIHOST_ERR2_PHYERR_ESC)
4534
- VEHICLE_DGERR("ERR2: escape entry error(ULPM), reg: 0x%x\n", val);
4535
- if (val & CSIHOST_ERR2_PHYERR_SOTHS)
4536
- VEHICLE_DGERR(
4537
- "ERR2: start of transmission error, reg: 0x%x\n", val);
4538
- if (val & CSIHOST_ERR2_ECC_CORRECTED)
4539
- VEHICLE_DGERR(
4540
- "ERR2: header error detected and corrected, reg: 0x%x\n", val);
4541
- if (val & CSIHOST_ERR2_ERR_ID)
4542
- VEHICLE_DGERR(
4543
- "ERR2: unrecognized data type detected, reg: 0x%x\n", val);
4544
- if (val & CSIHOST_ERR2_PHYERR_CODEHS)
4545
- VEHICLE_DGERR("ERR2: receive error code, reg: 0x%x\n", val);
4620
+ if (val & CSIHOST_ERR2_PHYERR_ESC) {
4621
+ vehicle_csi2_find_err_vc(val & 0xf, vc_info);
4622
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ULPM,lane:%s) ", vc_info);
4623
+ vehicle_csi2_err_strncat(err_str, cur_str);
4624
+ }
4625
+ if (val & CSIHOST_ERR2_PHYERR_SOTHS) {
4626
+ vehicle_csi2_find_err_vc((val >> 4) & 0xf, vc_info);
4627
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot,lane:%s) ", vc_info);
4628
+ vehicle_csi2_err_strncat(err_str, cur_str);
4629
+ }
4630
+ if (val & CSIHOST_ERR2_ECC_CORRECTED) {
4631
+ vehicle_csi2_find_err_vc((val >> 8) & 0xf, vc_info);
4632
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc,vc:%s) ", vc_info);
4633
+ vehicle_csi2_err_strncat(err_str, cur_str);
4634
+ }
4635
+ if (val & CSIHOST_ERR2_ERR_ID) {
4636
+ vehicle_csi2_find_err_vc((val >> 12) & 0xf, vc_info);
4637
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err id,vc:%s) ", vc_info);
4638
+ vehicle_csi2_err_strncat(err_str, cur_str);
4639
+ }
4640
+ if (val & CSIHOST_ERR2_PHYERR_CODEHS) {
4641
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err code) ");
4642
+ vehicle_csi2_err_strncat(err_str, cur_str);
4643
+ }
4644
+ cif->err_state.err_val = val;
4645
+ cif->err_state.err_num = 2;
4646
+ strscpy(cif->err_state.err_str, err_str, CSI_ERRSTR_LEN);
4647
+ queue_work(cif->err_state.err_print_wq, &cif->err_state.work);
4648
+
45464649 }
45474650
45484651 return IRQ_HANDLED;
....@@ -4661,6 +4764,7 @@
46614764 cif->stopping = true;
46624765 cancel_delayed_work_sync(&(cif->work));
46634766 flush_delayed_work(&(cif->work));
4767
+ cancel_work_sync(&cif->err_state.work);
46644768
46654769 ret = wait_event_timeout(cif->wq_stopped,
46664770 cif->state != RKCIF_STATE_STREAMING,
....@@ -5118,6 +5222,7 @@
51185222 if (inf_id == RKCIF_MIPI_LVDS) {
51195223 /* 5. set csi2-mipi-dphy reg */
51205224 if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 ||
5225
+ cif->dphy_hw->chip_id == CHIP_ID_RK3568 ||
51215226 cif->dphy_hw->chip_id == CHIP_ID_RK3562)
51225227 cif->dphy_hw->csi2_dphy_base = cif->csi2_dphy_base;
51235228
....@@ -5140,6 +5245,13 @@
51405245 init_waitqueue_head(&cif->wq_stopped);
51415246
51425247 spin_lock_init(&cif->vbq_lock);
5248
+
5249
+ INIT_WORK(&cif->err_state.work, vehicle_csi2_err_print_work);
5250
+ cif->err_state.err_print_wq = create_workqueue("cis2_err_print_queue");
5251
+ if (cif->err_state.err_print_wq == NULL) {
5252
+ dev_err(dev, "%s: %s create failed.\n", __func__,
5253
+ "csi2_err_print_wq");
5254
+ }
51435255
51445256 return 0;
51455257 }
....@@ -5211,6 +5323,10 @@
52115323 free_irq(cif->csi2_irq1, cif);
52125324 free_irq(cif->csi2_irq2, cif);
52135325 }
5326
+ if (cif->err_state.err_print_wq) {
5327
+ flush_workqueue(cif->err_state.err_print_wq);
5328
+ destroy_workqueue(cif->err_state.err_print_wq);
5329
+ }
52145330
52155331 return 0;
52165332 }