forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/video/rockchip/vehicle/vehicle_cif.c
....@@ -2266,6 +2266,31 @@
22662266 return index;
22672267 }
22682268
2269
+static enum cif_reg_index get_reg_index_of_frm_num(int channel_id)
2270
+{
2271
+ enum cif_reg_index index;
2272
+
2273
+ switch (channel_id) {
2274
+ case 0:
2275
+ index = CIF_REG_MIPI_FRAME_NUM_VC0;
2276
+ break;
2277
+ case 1:
2278
+ index = CIF_REG_MIPI_FRAME_NUM_VC1;
2279
+ break;
2280
+ case 2:
2281
+ index = CIF_REG_MIPI_FRAME_NUM_VC2;
2282
+ break;
2283
+ case 3:
2284
+ index = CIF_REG_MIPI_FRAME_NUM_VC3;
2285
+ break;
2286
+ default:
2287
+ index = CIF_REG_MIPI_FRAME_NUM_VC0;
2288
+ break;
2289
+ }
2290
+
2291
+ return index;
2292
+}
2293
+
22692294 static enum cif_reg_index get_reg_index_of_frm1_y_addr(int channel_id)
22702295 {
22712296 enum cif_reg_index index;
....@@ -2758,14 +2783,14 @@
27582783 VEHICLE_DG("%s, LINE=%d, channel->fmt_val = 0x%x", __func__, __LINE__, channel->fmt_val);
27592784 if (cfg->input_format == CIF_INPUT_FORMAT_PAL ||
27602785 cfg->input_format == CIF_INPUT_FORMAT_NTSC) {
2761
- VEHICLE_DG("CVBS IN PAL or NTSC config.");
2786
+ VEHICLE_INFO("CVBS IN PAL or NTSC config.");
27622787 channel->virtual_width *= 2;
27632788 cif->interlaced_enable = true;
27642789 cif->interlaced_offset = channel->width;
27652790 cif->interlaced_counts = 0;
27662791 cif->interlaced_buffer = 0;
27672792 channel->height /= 2;
2768
- VEHICLE_DG("do denterlaced.\n");
2793
+ VEHICLE_INFO("do denterlaced.\n");
27692794 }
27702795
27712796 channel->data_type = get_data_type(cfg->mbus_code,
....@@ -3930,7 +3955,7 @@
39303955 static unsigned long temp_y_addr, temp_uv_addr;
39313956 int commit_buf = 0;
39323957 struct vehicle_rkcif_dummy_buffer *dummy_buf = &cif->dummy_buf;
3933
-
3958
+ u32 frm_num_reg, frame_id = 0;
39343959 VEHICLE_DG("@%s, enter, mipi_id(%d)\n", __func__, mipi_id);
39353960
39363961 if ((frame_ready > 1) || (cif->cif_cfg.buf_num < 2) ||
....@@ -3946,6 +3971,10 @@
39463971 frm0_addr_uv = get_reg_index_of_frm0_uv_addr(mipi_id);
39473972 frm1_addr_y = get_reg_index_of_frm1_y_addr(mipi_id);
39483973 frm1_addr_uv = get_reg_index_of_frm1_uv_addr(mipi_id);
3974
+ frm_num_reg = get_reg_index_of_frm_num(mipi_id);
3975
+ frame_id = rkcif_read_reg(cif, frm_num_reg);
3976
+ VEHICLE_DG("@%s, frm_num_reg(0x%x), frame_id:0x%x\n", __func__,
3977
+ frm_num_reg, frame_id);
39493978 } else {
39503979 frm0_addr_y = get_dvp_reg_index_of_frm0_y_addr(mipi_id);
39513980 frm0_addr_uv = get_dvp_reg_index_of_frm0_uv_addr(mipi_id);
....@@ -3979,10 +4008,11 @@
39794008 uv_addr = temp_uv_addr;
39804009 commit_buf = 0;
39814010 } else {
3982
- if ((cif->interlaced_counts % 2) == 0) {
4011
+ if ((frame_id != 0 && (frame_id & 0xffff) % 2 == 0) ||
4012
+ (frame_id == 0 && (cif->interlaced_counts % 2 == 0))) {
39834013 temp_y_addr = vehicle_flinger_request_cif_buffer();
39844014 if (temp_y_addr == 0) {
3985
- VEHICLE_INFO("%s,warnning request buffer failed\n", __func__);
4015
+ VEHICLE_DGERR("%s,warnning request buffer failed\n", __func__);
39864016 spin_unlock(&cif->vbq_lock);
39874017 return -1;
39884018 }
....@@ -3995,6 +4025,11 @@
39954025 //uv_addr = temp_uv_addr;
39964026 uv_addr = temp_uv_addr + cif->interlaced_offset;
39974027 commit_buf = 0; //even & odd field add
4028
+ if (temp_y_addr == 0) {
4029
+ VEHICLE_DGERR("%s,warnning temp_y_addr is NULL!\n", __func__);
4030
+ spin_unlock(&cif->vbq_lock);
4031
+ return -1;
4032
+ }
39984033 }
39994034 WARN_ON(y_addr == cif->interlaced_offset);
40004035 WARN_ON(uv_addr == cif->interlaced_offset);
....@@ -4453,6 +4488,37 @@
44534488 return IRQ_HANDLED;
44544489 }
44554490
4491
+#define vehicle_csi2_err_strncat(dst_str, src_str) {\
4492
+ if (strlen(dst_str) + strlen(src_str) < CSI_ERRSTR_LEN)\
4493
+ strncat(dst_str, src_str, strlen(src_str)); }
4494
+
4495
+static void vehicle_csi2_find_err_vc(int val, char *vc_info)
4496
+{
4497
+ int i;
4498
+ char cur_str[CSI_VCINFO_LEN] = {0};
4499
+
4500
+ memset(vc_info, 0, sizeof(*vc_info));
4501
+ for (i = 0; i < 4; i++) {
4502
+ if ((val >> i) & 0x1) {
4503
+ snprintf(cur_str, CSI_VCINFO_LEN, " %d", i);
4504
+ if (strlen(vc_info) + strlen(cur_str) < CSI_VCINFO_LEN)
4505
+ strncat(vc_info, cur_str, strlen(cur_str));
4506
+ }
4507
+ }
4508
+}
4509
+
4510
+static void vehicle_csi2_err_print_work(struct work_struct *work)
4511
+{
4512
+ struct vehicle_csi2_err_state_work *err_state = container_of(work,
4513
+ struct vehicle_csi2_err_state_work,
4514
+ work);
4515
+
4516
+ pr_err("mipi_csi2: ERR%d:0x%x %s\n", err_state->err_num,
4517
+ err_state->err_val, err_state->err_str);
4518
+ if (err_state->err_num == 1)
4519
+ pr_info("mipi_csi2: err_stat:0x%x\n", err_state->err_stat);
4520
+}
4521
+
44564522 static irqreturn_t vehicle_csirx_irq1(int irq, void *data)
44574523 {
44584524 struct vehicle_cif *cif = (struct vehicle_cif *)data;
....@@ -4460,6 +4526,9 @@
44604526 struct csi2_err_stats *err_list = NULL;
44614527 unsigned long err_stat = 0;
44624528 u32 val;
4529
+ char err_str[CSI_ERRSTR_LEN] = {0};
4530
+ char cur_str[CSI_ERRSTR_LEN] = {0};
4531
+ char vc_info[CSI_VCINFO_LEN] = {0};
44634532
44644533 val = read_reg(hw->csi2_base, CSIHOST_ERR1);
44654534 if (val) {
....@@ -4469,53 +4538,69 @@
44694538 if (val & CSIHOST_ERR1_PHYERR_SPTSYNCHS) {
44704539 err_list = &hw->err_list[RK_CSI2_ERR_SOTSYN];
44714540 err_list->cnt++;
4472
- VEHICLE_DGERR(
4473
- "ERR1: start of transmission error, reg: 0x%x,cnt:%d\n",
4474
- val, err_list->cnt);
4541
+
4542
+ vehicle_csi2_find_err_vc(val & 0xf, vc_info);
4543
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot sync,lane:%s) ", vc_info);
4544
+ vehicle_csi2_err_strncat(err_str, cur_str);
44754545 }
44764546
44774547 if (val & CSIHOST_ERR1_ERR_BNDRY_MATCH) {
44784548 err_list = &hw->err_list[RK_CSI2_ERR_FS_FE_MIS];
44794549 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);
4550
+ vehicle_csi2_find_err_vc((val >> 4) & 0xf, vc_info);
4551
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(fs/fe miss,vc:%s) ", vc_info);
4552
+ vehicle_csi2_err_strncat(err_str, cur_str);
4553
+
44834554 }
44844555
44854556 if (val & CSIHOST_ERR1_ERR_SEQ) {
44864557 err_list = &hw->err_list[RK_CSI2_ERR_FRM_SEQ_ERR];
44874558 err_list->cnt++;
4488
- VEHICLE_DGERR("ERR1: incorrect frame sequence detected, reg: 0x%x,cnt:%d\n",
4489
- val, err_list->cnt);
4559
+ vehicle_csi2_find_err_vc((val >> 8) & 0xf, vc_info);
4560
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(f_seq,vc:%s) ", vc_info);
4561
+ vehicle_csi2_err_strncat(err_str, cur_str);
4562
+
44904563 }
44914564
44924565 if (val & CSIHOST_ERR1_ERR_FRM_DATA) {
44934566 err_list = &hw->err_list[RK_CSI2_ERR_CRC_ONCE];
44944567 err_list->cnt++;
4495
- VEHICLE_DGERR("ERR1: at least one crc error, reg: 0x%x\n,cnt:%d",
4496
- val, err_list->cnt);
4568
+ vehicle_csi2_find_err_vc((val >> 12) & 0xf, vc_info);
4569
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err_data,vc:%s) ", vc_info);
4570
+ vehicle_csi2_err_strncat(err_str, cur_str);
4571
+
44974572 }
44984573
44994574 if (val & CSIHOST_ERR1_ERR_CRC) {
45004575 err_list = &hw->err_list[RK_CSI2_ERR_CRC];
45014576 err_list->cnt++;
4502
- VEHICLE_DGERR("ERR1: crc errors, reg: 0x%x, cnt:%d\n",
4503
- val, err_list->cnt);
4577
+ vehicle_csi2_find_err_vc((val >> 24) & 0xf, vc_info);
4578
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(crc,vc:%s) ", vc_info);
4579
+ vehicle_csi2_err_strncat(err_str, cur_str);
4580
+
45044581 }
45054582
45064583 if (val & CSIHOST_ERR1_ERR_ECC2) {
45074584 err_list = &hw->err_list[RK_CSI2_ERR_CRC];
45084585 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);
4586
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc2) ");
4587
+ vehicle_csi2_err_strncat(err_str, cur_str);
45144588
4589
+ }
4590
+ if (val & CSIHOST_ERR1_ERR_CTRL) {
4591
+ vehicle_csi2_find_err_vc((val >> 16) & 0xf, vc_info);
4592
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ctrl,vc:%s) ", vc_info);
4593
+ vehicle_csi2_err_strncat(err_str, cur_str);
4594
+ }
45154595 hw->err_list[RK_CSI2_ERR_ALL].cnt++;
45164596 err_stat = ((hw->err_list[RK_CSI2_ERR_FS_FE_MIS].cnt & 0xff) << 8) |
45174597 ((hw->err_list[RK_CSI2_ERR_ALL].cnt) & 0xff);
4518
- VEHICLE_INFO("%s: err_stat: %x\n", err_stat);
4598
+
4599
+ cif->err_state.err_val = val;
4600
+ cif->err_state.err_num = 1;
4601
+ cif->err_state.err_stat = err_stat;
4602
+ strscpy(cif->err_state.err_str, err_str, CSI_ERRSTR_LEN);
4603
+ queue_work(cif->err_state.err_print_wq, &cif->err_state.work);
45194604
45204605 }
45214606
....@@ -4527,22 +4612,41 @@
45274612 struct vehicle_cif *cif = (struct vehicle_cif *)data;
45284613 struct csi2_dphy_hw *hw = cif->dphy_hw;
45294614 u32 val;
4615
+ char cur_str[CSI_ERRSTR_LEN] = {0};
4616
+ char err_str[CSI_ERRSTR_LEN] = {0};
4617
+ char vc_info[CSI_VCINFO_LEN] = {0};
45304618
45314619 val = read_reg(hw->csi2_base, CSIHOST_ERR2);
45324620 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);
4621
+ if (val & CSIHOST_ERR2_PHYERR_ESC) {
4622
+ vehicle_csi2_find_err_vc(val & 0xf, vc_info);
4623
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ULPM,lane:%s) ", vc_info);
4624
+ vehicle_csi2_err_strncat(err_str, cur_str);
4625
+ }
4626
+ if (val & CSIHOST_ERR2_PHYERR_SOTHS) {
4627
+ vehicle_csi2_find_err_vc((val >> 4) & 0xf, vc_info);
4628
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(sot,lane:%s) ", vc_info);
4629
+ vehicle_csi2_err_strncat(err_str, cur_str);
4630
+ }
4631
+ if (val & CSIHOST_ERR2_ECC_CORRECTED) {
4632
+ vehicle_csi2_find_err_vc((val >> 8) & 0xf, vc_info);
4633
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(ecc,vc:%s) ", vc_info);
4634
+ vehicle_csi2_err_strncat(err_str, cur_str);
4635
+ }
4636
+ if (val & CSIHOST_ERR2_ERR_ID) {
4637
+ vehicle_csi2_find_err_vc((val >> 12) & 0xf, vc_info);
4638
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err id,vc:%s) ", vc_info);
4639
+ vehicle_csi2_err_strncat(err_str, cur_str);
4640
+ }
4641
+ if (val & CSIHOST_ERR2_PHYERR_CODEHS) {
4642
+ snprintf(cur_str, CSI_ERRSTR_LEN, "(err code) ");
4643
+ vehicle_csi2_err_strncat(err_str, cur_str);
4644
+ }
4645
+ cif->err_state.err_val = val;
4646
+ cif->err_state.err_num = 2;
4647
+ strscpy(cif->err_state.err_str, err_str, CSI_ERRSTR_LEN);
4648
+ queue_work(cif->err_state.err_print_wq, &cif->err_state.work);
4649
+
45464650 }
45474651
45484652 return IRQ_HANDLED;
....@@ -4661,6 +4765,7 @@
46614765 cif->stopping = true;
46624766 cancel_delayed_work_sync(&(cif->work));
46634767 flush_delayed_work(&(cif->work));
4768
+ cancel_work_sync(&cif->err_state.work);
46644769
46654770 ret = wait_event_timeout(cif->wq_stopped,
46664771 cif->state != RKCIF_STATE_STREAMING,
....@@ -5118,6 +5223,7 @@
51185223 if (inf_id == RKCIF_MIPI_LVDS) {
51195224 /* 5. set csi2-mipi-dphy reg */
51205225 if (cif->dphy_hw->chip_id == CHIP_ID_RK3588 ||
5226
+ cif->dphy_hw->chip_id == CHIP_ID_RK3568 ||
51215227 cif->dphy_hw->chip_id == CHIP_ID_RK3562)
51225228 cif->dphy_hw->csi2_dphy_base = cif->csi2_dphy_base;
51235229
....@@ -5140,6 +5246,13 @@
51405246 init_waitqueue_head(&cif->wq_stopped);
51415247
51425248 spin_lock_init(&cif->vbq_lock);
5249
+
5250
+ INIT_WORK(&cif->err_state.work, vehicle_csi2_err_print_work);
5251
+ cif->err_state.err_print_wq = create_workqueue("cis2_err_print_queue");
5252
+ if (cif->err_state.err_print_wq == NULL) {
5253
+ dev_err(dev, "%s: %s create failed.\n", __func__,
5254
+ "csi2_err_print_wq");
5255
+ }
51435256
51445257 return 0;
51455258 }
....@@ -5211,6 +5324,10 @@
52115324 free_irq(cif->csi2_irq1, cif);
52125325 free_irq(cif->csi2_irq2, cif);
52135326 }
5327
+ if (cif->err_state.err_print_wq) {
5328
+ flush_workqueue(cif->err_state.err_print_wq);
5329
+ destroy_workqueue(cif->err_state.err_print_wq);
5330
+ }
52145331
52155332 return 0;
52165333 }