diff --git a/driver/common/bm_printk.h b/driver/common/bm_printk.h index 4490bee..dcaecce 100644 --- a/driver/common/bm_printk.h +++ b/driver/common/bm_printk.h @@ -37,7 +37,7 @@ #define bm_notice(fmt, ...) \ printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) #define bm_info(fmt, ...) \ - printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #else #define bm_notice(fmt, ...) #define bm_info(fmt, ...) diff --git a/driver/csi/bm_csi_driver.c b/driver/csi/bm_csi_driver.c index de406e0..86fc9c4 100644 --- a/driver/csi/bm_csi_driver.c +++ b/driver/csi/bm_csi_driver.c @@ -32,6 +32,7 @@ #include #include +#include #include "bm_printk.h" #include "bm_csi_ioctl.h" @@ -52,9 +53,10 @@ static unsigned int device_register_index = 0; return -EIO;\ } while (0) -static unsigned int bm_csi_poll(struct file * filp, poll_table *wait) +extern unsigned csi_poll(struct file *file, struct poll_table_struct *wait); +static unsigned int bm_csi_poll(struct file * filp, struct poll_table_struct *wait) { - return 0; + return csi_poll(filp, wait); } void bm_csi_work(struct work_struct *work) @@ -70,7 +72,7 @@ irqreturn_t bm_csi_irq(int irq, void *dev_id) static int bm_csi_runtime_suspend(struct device *dev) { struct bm_csi_drvdata *pdriver_dev = dev_get_drvdata(dev); - dev_info(dev, "enter %s\n", __func__); + bm_info("enter %s\n", __func__); if (pdriver_dev->pclk != NULL) { clk_disable_unprepare(pdriver_dev->pclk); @@ -99,7 +101,7 @@ static int bm_csi_runtime_resume(struct device *dev) { int ret = 0; struct bm_csi_drvdata *pdriver_dev = dev_get_drvdata(dev); - dev_info(dev, "enter %s\n", __func__); + bm_info("enter %s\n", __func__); if (pdriver_dev->pclk != NULL) { ret = clk_prepare_enable(pdriver_dev->pclk); @@ -161,12 +163,19 @@ static int bm_csi_open(struct inode * inode, struct file * file) struct device *dev; bm_info("enter %s\n", __func__); - dev_info(dev, "open mipi-csi dev\n"); + bm_info("open mipi-csi dev\n"); drvdata = container_of(inode->i_cdev, struct bm_csi_drvdata, cdev); file->private_data = drvdata; dev = &drvdata->pdev->dev; - dev_info(dev, "open mipi-csi dev\n"); + drvdata->csi_power_on_sta = 0; + memset(&drvdata->csi_dev.hw, 0, sizeof(drvdata->csi_dev.hw)); + drvdata->csi_dev.hw.ipi_mode = CAMERA_TIMING; + drvdata->csi_dev.hw.ipi_color_mode = COLOR16; + + memset(&drvdata->csi_dev.error_mask, 0, sizeof(drvdata->csi_dev.error_mask)); + + bm_info("open mipi-csi dev\n"); if (pm_runtime_get_sync(dev)) { ret = bm_csi_runtime_resume(dev); if (ret) @@ -196,6 +205,9 @@ static long bm_csi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case BMCSI_IOC_READ_REG: ret = bm_csi_read_reg(drvdata, (void *)arg); break; + case BMCSI_IOC_READ_ARRAY: + ret = bm_csi_read_array(drvdata, (void *)arg); + break; case BMCSI_IOC_S_RESET: ret = bm_csi_reset(drvdata, (void *)arg); break; @@ -253,6 +265,9 @@ static long bm_csi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case BMCSI_IOC_GET_PIXCLK: ret = bm_csi_get_pixclk(drvdata, (void *)arg); break; + case BMCSI_IOC_GET_ERROR: + ret = bm_csi_get_error(drvdata, (void *)arg); + break; case BMCSI_IOC_MAX: break; default: @@ -275,7 +290,7 @@ static int bm_csi_release(struct inode * inode, struct file * file) drvdata = container_of(inode->i_cdev, struct bm_csi_drvdata, cdev); file->private_data = drvdata; dev = &drvdata->pdev->dev; - dev_info(dev, "release mipi-csi dev\n"); + bm_info("release mipi-csi dev\n"); ret = bm_csi_dis_power(drvdata); if (ret) { pr_info("fail to disable csi power, %s %d\n", __func__, __LINE__); @@ -311,6 +326,7 @@ static int bm_csi_probe(struct platform_device *pdev) struct resource *iores_mem; unsigned int dphyglueiftester= 0; unsigned int sysreg_mipi_csi_ctrl = 0; + struct device_node *np = pdev->dev.of_node; u32 value; bm_info("enter %s\n", __func__); @@ -326,11 +342,43 @@ static int bm_csi_probe(struct platform_device *pdev) return -ENOMEM; } + memset(drvdata, 0, sizeof(*drvdata)); + iores_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); drvdata->base = devm_ioremap_resource(&pdev->dev, iores_mem); + bm_info("%s: [%s%d]: drvdata->base=0x%px, phy_addr base=0x%llx\n", __func__, BM_DRIVER_NAME, pdev->id, drvdata->base, iores_mem->start); + /* + if (iores_mem->start == 0xffe4010000) { + drvdata->visys_clk_reg = syscon_regmap_lookup_by_phandle(np, "visys-regmap"); + if (IS_ERR(drvdata->visys_clk_reg)) { + drvdata->visys_clk_reg = NULL; + dev_err(&pdev->dev, "cannot find regmap for visys clk register\n"); + } + + drvdata->csia_reg = syscon_regmap_lookup_by_phandle(np, "csia-regmap"); + if (IS_ERR(drvdata->csia_reg)) { + drvdata->csia_reg = NULL; + dev_err(&pdev->dev, "cannot find regmap for csia register\n"); + } + } + */ + + const char *phy_name; + ret = of_property_read_string(np, "phy_name", &phy_name); + if (strcmp(phy_name, "CSI_B") == 0) { + bm_info("mipi is b phy\n"); + drvdata->phy_id = MIPI_B_PHY; + } else if(strcmp(phy_name, "CSI_A") == 0) { + bm_info("mipi is a phy\n"); + drvdata->phy_id = MIPI_A_PHY; + } else if(strcmp(phy_name, "CSI_4LANE") == 0) { + bm_info("mipi is 4lane phy\n"); + drvdata->phy_id = MIPI_4LANE_PHY; + } + drvdata->reset = NULL; drvdata->device_idx = pdev->id; mutex_init(&drvdata->mutex); @@ -420,16 +468,16 @@ static int bm_csi_probe(struct platform_device *pdev) device_property_read_u32(&pdev->dev, "sysreg_mipi_csi_ctrl", &sysreg_mipi_csi_ctrl); bm_info("sysreg_mipi_csi_ctrl is:0x%x\n", sysreg_mipi_csi_ctrl); - dw_dphy_rx_probe(pdev, dphyglueiftester, sysreg_mipi_csi_ctrl); - dw_csi_probe(pdev); - pm_runtime_enable(&pdev->dev); - ret = bm_csi_runtime_resume(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "fail to resume csi\n"); } - ret = bm_csi_runtime_suspend(&pdev->dev); + dw_dphy_rx_probe(pdev, dphyglueiftester, sysreg_mipi_csi_ctrl); + dw_csi_probe(pdev); + + ret = pm_runtime_put_sync(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "fail to suspend csi\n"); } diff --git a/driver/csi/bm_csi_hw.c b/driver/csi/bm_csi_hw.c index 8761a27..03e32b1 100644 --- a/driver/csi/bm_csi_hw.c +++ b/driver/csi/bm_csi_hw.c @@ -31,6 +31,7 @@ #include #include +#include #include "bm_printk.h" #include "bm_csi_ioctl.h" @@ -70,6 +71,24 @@ int bm_csi_read_reg(struct bm_csi_drvdata *drvdata, void *__user args) return 0; } +int bm_csi_read_array(struct bm_csi_drvdata *drvdata, void *__user args) +{ + int index = 0; + int cnt = 0; + uint32_t value = 0; + struct bm_csi_reg_arry_t array; + + check_retval(copy_from_user(&array, args, sizeof(struct bm_csi_reg_arry_t))); + cnt = array.words; + + for (index = 0; index < cnt; index++) { + value = readl(drvdata->base + array.start_addr + index * 4); + check_retval(copy_to_user(&(array.buf[index]), &value, sizeof(value))); + } + + return 0; +} + int bm_csi_reset(struct bm_csi_drvdata *drvdata, void *__user args) { bm_info("%s: csi reset success\n", __func__); @@ -79,36 +98,62 @@ int bm_csi_reset(struct bm_csi_drvdata *drvdata, void *__user args) return 0; } -static uint32_t csi_power_on_sta = 0; - int bm_csi_en_power(struct bm_csi_drvdata *drvdata) { bm_info("%s: csi set power\n", __func__); - csi_power_on_sta = 1; - dw_mipi_csi_s_power(&drvdata->csi_dev, csi_power_on_sta); + drvdata->csi_power_on_sta = 1; + dw_mipi_csi_s_power(&drvdata->csi_dev, drvdata->csi_power_on_sta); return 0; } int bm_csi_dis_power(struct bm_csi_drvdata *drvdata) { bm_info("%s: csi set power\n", __func__); - csi_power_on_sta = 0; - dw_mipi_csi_s_power(&drvdata->csi_dev, csi_power_on_sta); + drvdata->csi_power_on_sta = 0; + dw_mipi_csi_s_power(&drvdata->csi_dev, drvdata->csi_power_on_sta); return 0; } +static int bm_csi_can_enable(struct bm_csi_drvdata *drvdata) +{ + return 1; + u32 csia_pixclk = 0; + u32 csia_rst = 0; + u32 csia_shutdown = 0; + + if (drvdata->csia_reg == NULL || drvdata->visys_clk_reg == NULL) { + return 1; + } + + regmap_read(drvdata->visys_clk_reg, 0xa0, &csia_pixclk); + regmap_read(drvdata->csia_reg, 0x40 + R_CSI2_DPHY_RSTZ, &csia_rst); + regmap_read(drvdata->csia_reg, 0x40 + R_CSI2_DPHY_SHUTDOWNZ, &csia_shutdown); + + if (csia_pixclk & (1 << 9) && (csia_rst | csia_shutdown)) { + return 0; + } + + return 1; +} + int bm_csi_set_power(struct bm_csi_drvdata *drvdata, void *__user args) { bm_info("%s: csi set power\n", __func__); - check_retval(copy_from_user(&csi_power_on_sta, args, sizeof(csi_power_on_sta))); - dw_mipi_csi_s_power(&drvdata->csi_dev, csi_power_on_sta); + check_retval(copy_from_user(&drvdata->csi_power_on_sta, args, sizeof(drvdata->csi_power_on_sta))); + + if (!bm_csi_can_enable(drvdata)) { + printk("can't enable csi power!!!!!!!!!!!!!\n"); + return -1; + } + + dw_mipi_csi_s_power(&drvdata->csi_dev, drvdata->csi_power_on_sta); return 0; } int bm_csi_get_power(struct bm_csi_drvdata *drvdata, void *__user args) { bm_info("%s: csi get power\n", __func__); - check_retval(copy_to_user(args, &csi_power_on_sta, sizeof(csi_power_on_sta))); + check_retval(copy_to_user(args, &drvdata->csi_power_on_sta, sizeof(drvdata->csi_power_on_sta))); return 0; } @@ -146,6 +191,14 @@ int bm_csi_get_pixclk(struct bm_csi_drvdata *drvdata, void *__user args) return 0; } +int bm_csi_get_error(struct bm_csi_drvdata *drvdata, void *__user args) +{ + bm_info("%s: \n", __func__); + struct dw_csi_err_mask *error_mask = &drvdata->csi_dev.error_mask; + check_retval(copy_to_user(args, error_mask, sizeof(struct dw_csi_err_mask))); + return 0; +} + int bm_csi_set_stream(struct bm_csi_drvdata *drvdata, void *__user args) { bm_info("%s: \n", __func__); @@ -155,7 +208,7 @@ int bm_csi_set_stream(struct bm_csi_drvdata *drvdata, void *__user args) int bm_csi_get_stream(struct bm_csi_drvdata *drvdata, void *__user args) { bm_info("%s: \n", __func__); - check_retval(copy_to_user(args, &csi_power_on_sta, sizeof(csi_power_on_sta))); + check_retval(copy_to_user(args, &drvdata->csi_power_on_sta, sizeof(drvdata->csi_power_on_sta))); return 0; } @@ -209,13 +262,10 @@ int bm_csi_set_vc_select(struct bm_csi_drvdata *drvdata, void *__user args) check_retval(copy_from_user(&vc, args, sizeof(vc))); if (vc.ipi_idx == 1) { - csi_dev->hw.ipi1_en = true; csi_dev->hw.virtual_ch = vc.vc_ch; } else if (vc.ipi_idx == 2) { - csi_dev->hw.ipi2_en = true; csi_dev->hw.ipi2_virtual_ch = vc.vc_ch; } else if (vc.ipi_idx == 3) { - csi_dev->hw.ipi3_en = true; csi_dev->hw.ipi3_virtual_ch = vc.vc_ch; } @@ -227,6 +277,12 @@ int bm_csi_ipi_enable(struct bm_csi_drvdata *drvdata, void *__user args) int ipi_idx; struct dw_csi *csi_dev = &drvdata->csi_dev; bm_info("%s: \n", __func__); + + if (!bm_csi_can_enable(drvdata)) { + printk("can't enable csi ipi!!!!!!!!!!!!!\n"); + return -1; + } + check_retval(copy_from_user(&ipi_idx, args, sizeof(ipi_idx))); if (ipi_idx == 1) { diff --git a/driver/csi/bm_csi_hw.h b/driver/csi/bm_csi_hw.h index 0c50e10..0f594e6 100644 --- a/driver/csi/bm_csi_hw.h +++ b/driver/csi/bm_csi_hw.h @@ -23,7 +23,10 @@ struct bm_csi_drvdata { struct mutex mutex; unsigned int device_idx; void __iomem *base; + struct regmap *csia_reg; + struct regmap *visys_clk_reg; void __iomem *reset; + phy_id_e phy_id; struct dw_dphy_rx *dphy; struct dw_csi csi_dev; struct dw_csih_pdata csi_pdata; @@ -35,6 +38,8 @@ struct bm_csi_drvdata { struct clk *cfg_clk1; struct clk *cfg_clk2; struct platform_device *pdev; + uint32_t csi_power_on_sta; + wait_queue_head_t irq_wait; void *private; // can be bm_csi_drvdata_private, but not use now }; @@ -44,6 +49,7 @@ struct bm_csi_drvdata_private { int bm_csi_write_reg(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_read_reg(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_read_array(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_init(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_exit(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_reset(struct bm_csi_drvdata *drvdata, void *__user args); @@ -57,6 +63,7 @@ int bm_csi_set_pixclk(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_get_pixclk(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_set_stream(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_get_stream(struct bm_csi_drvdata *drvdata, void *__user args); +int bm_csi_get_error(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_set_fmt(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_get_fmt(struct bm_csi_drvdata *drvdata, void *__user args); int bm_csi_set_vc_select(struct bm_csi_drvdata *drvdata, void *__user args); diff --git a/driver/csi/bm_csi_ioctl.h b/driver/csi/bm_csi_ioctl.h index 0db8508..c92a244 100644 --- a/driver/csi/bm_csi_ioctl.h +++ b/driver/csi/bm_csi_ioctl.h @@ -31,8 +31,10 @@ enum { BMCSI_IOC_S_HSD_CFG, BMCSI_IOC_WRITE_REG, BMCSI_IOC_READ_REG, + BMCSI_IOC_READ_ARRAY, BMCSI_IOC_SET_PIXCLK, BMCSI_IOC_GET_PIXCLK, + BMCSI_IOC_GET_ERROR, BMCSI_IOC_MAX, }; @@ -41,9 +43,35 @@ struct bm_csi_reg_t { unsigned int value; }; +struct bm_csi_reg_arry_t { + unsigned int start_addr; + unsigned int words; + unsigned int *buf; +}; + struct csi_vc_select_context { unsigned int ipi_idx; unsigned int vc_ch; }; +struct dw_csi_err_mask { + unsigned int src; + unsigned int ipi1_phy_fatal_mask; + unsigned int ipi2_phy_fatal_mask; + unsigned int ipi3_phy_fatal_mask; + unsigned int pkt_fatal; + unsigned int frame_fatal; + unsigned int phy; + unsigned int line; + unsigned int ipi; + unsigned int ipi2; + unsigned int ipi3; + unsigned int bndry_frame_fatal; + unsigned int seq_frame_fatal; + unsigned int crc_frame_fatal; + unsigned int pld_crc_fatal; + unsigned int data_id; + unsigned int ecc_corrected; +}; + #endif /* _BM_CSI_IOCTL_H_*/ diff --git a/driver/csi/dw-csi-plat.c b/driver/csi/dw-csi-plat.c index 5b658e5..a4d27d4 100644 --- a/driver/csi/dw-csi-plat.c +++ b/driver/csi/dw-csi-plat.c @@ -114,13 +114,13 @@ dw_mipi_csi_try_format(uint32_t mbus_code) struct mipi_fmt * dw_mipi_csi_get_format(struct dw_csi *dev) { - dev_info(dev->dev, + dev_vdbg(dev->dev, "%s got v4l2_mbus_pixelcode. 0x%x\n", __func__, dev->fmt->mbus_code); - dev_info(dev->dev, + dev_vdbg(dev->dev, "%s got width. 0x%x\n", __func__, dev->fmt->width); - dev_info(dev->dev, + dev_vdbg(dev->dev, "%s got height. 0x%x\n", __func__, dev->fmt->height); return dev->fmt; @@ -135,13 +135,13 @@ dw_mipi_csi_set_fmt(struct platform_device *pdev, struct mipi_fmt *dev_fmt = NULL; int i; - dev_info(dev->dev, + dev_vdbg(dev->dev, "%s got mbus_pixelcode. 0x%x\n", __func__, mbus_code); dev_fmt = dw_mipi_csi_try_format(mbus_code); - dev_info(dev->dev, + dev_vdbg(dev->dev, "%s got v4l2_mbus_pixelcode. 0x%x\n", __func__, dev_fmt->mbus_code); if (!dev_fmt) @@ -153,7 +153,7 @@ dw_mipi_csi_set_fmt(struct platform_device *pdev, dev->fmt->height = height; dw_mipi_csi_set_ipi_fmt(dev); } - dev_info(dev->dev, "Width: %d, Height: %d of Demo\n", width, height); + dev_vdbg(dev->dev, "Width: %d, Height: %d of Demo\n", width, height); if (width > 0 && height > 0) { dw_mipi_csi_fill_timings(dev, width, height); /* @@ -170,7 +170,7 @@ dw_mipi_csi_set_fmt(struct platform_device *pdev, width, dev->hw.vactive, height); - dev_info(dev->dev, + dev_vdbg(dev->dev, "(core/demosaic) : width=%d/%d, height=%d/%d\n", dev->hw.htotal - (dev->hw.hbp + dev->hw.hsd @@ -184,9 +184,9 @@ dw_mipi_csi_set_fmt(struct platform_device *pdev, __func__, width); dev_vdbg(dev->dev, "%s unacceptable values 0x%x.\n", __func__, height); - dev_info(dev->dev, "%s unacceptable values 0x%x.\n", + dev_vdbg(dev->dev, "%s unacceptable values 0x%x.\n", __func__, width); - dev_info(dev->dev, "%s unacceptable values 0x%x.\n", + dev_vdbg(dev->dev, "%s unacceptable values 0x%x.\n", __func__, height); return -EINVAL; } @@ -195,7 +195,7 @@ dw_mipi_csi_set_fmt(struct platform_device *pdev, if (csi_dt[i].hex == dev->ipi_dt) { dev_vdbg(dev->dev, "Using data type %s\n", csi_dt[i].name); - dev_info(dev->dev, "Using data type %s\n", + dev_vdbg(dev->dev, "Using data type %s\n", csi_dt[i].name); } return 0; @@ -221,14 +221,14 @@ dw_mipi_csi_get_fmt(struct platform_device *pdev, int dw_mipi_csi_s_power(struct dw_csi *dev, int on) { - dev_info(dev->dev, "%s: on=%d\n", __func__, on); + dev_vdbg(dev->dev, "%s: on=%d\n", __func__, on); if (on) { dw_dphy_power_on(dev->phy); dw_mipi_csi_hw_stdby(dev); dw_mipi_csi_start(dev); } else { - phy_power_off(dev->phy); + dw_dphy_power_off(dev->phy); dw_mipi_csi_mask_irq_power_off(dev); /* reset data type */ dev->ipi_dt = 0x0; @@ -272,11 +272,32 @@ static int dw_mipi_csi_init_cfg(struct v4l2_subdev *sd, } #endif +unsigned csi_poll(struct file *file, struct poll_table_struct *wait) +{ + unsigned int mask = 0; + struct bm_csi_drvdata *drvdata = file->private_data; + struct dw_csi *csi_dev = &drvdata->csi_dev; + struct dw_csi_err_mask *err_mask = &csi_dev->error_mask; + + poll_wait(file, &drvdata->irq_wait, wait); + + if (csi_dev->has_error) { + csi_dev->has_error = 0; + mask |= POLLIN | POLLRDNORM; + } + + return mask; +} + + static irqreturn_t dw_mipi_csi_irq1(int irq, void *dev_id) { - struct dw_csi *csi_dev = dev_id; + + struct bm_csi_drvdata *drvdata = dev_id; + struct dw_csi *csi_dev = &drvdata->csi_dev; dw_mipi_csi_irq_handler(csi_dev); + wake_up_interruptible(&drvdata->irq_wait); return IRQ_HANDLED; } @@ -369,7 +390,7 @@ int dw_csi_probe(struct platform_device *pdev) ret = devm_request_irq(dev, csi->ctrl_irq_number, dw_mipi_csi_irq1, IRQF_SHARED, - dev_name(dev), csi); + dev_name(dev), drvdata); if (ret) { dev_err(dev, "irq csi %d failed\n", pdata->id); goto end; @@ -387,6 +408,7 @@ int dw_csi_probe(struct platform_device *pdev) csi->hw.ipi_mode = CAMERA_TIMING; csi->hw.ipi_color_mode = COLOR16; + init_waitqueue_head(&drvdata->irq_wait); //csi soc reset dw_csi_soc_reset(); dw_csi_create_capabilities_sysfs(pdev); @@ -394,7 +416,7 @@ int dw_csi_probe(struct platform_device *pdev) dw_mipi_csi_specific_mappings(csi); dw_mipi_csi_mask_irq_power_off(csi); - dev_info(dev, "DW MIPI CSI-2 Host registered successfully HW v%u.%u\n", + dev_vdbg(dev, "DW MIPI CSI-2 Host registered successfully HW v%u.%u\n", csi->hw_version_major, csi->hw_version_minor); ret = phy_reset(csi->phy); @@ -421,7 +443,7 @@ int dw_csi_remove(struct platform_device *pdev) //struct dw_csi *mipi_csi = &drvdata->csi_dev; //csi soc reset dw_csi_soc_reset(); - dev_info(&pdev->dev, "DW MIPI CSI-2 Host module removed\n"); + dev_vdbg(&pdev->dev, "DW MIPI CSI-2 Host module removed\n"); return 0; } diff --git a/driver/csi/dw-csi-sysfs.c b/driver/csi/dw-csi-sysfs.c index 8709561..3e8f7f9 100644 --- a/driver/csi/dw-csi-sysfs.c +++ b/driver/csi/dw-csi-sysfs.c @@ -46,7 +46,7 @@ static ssize_t n_lanes_store(struct device *dev, struct device_attribute *attr, return count; } - dev_info(dev, "Lanes %lu\n", lanes); + dev_vdbg(dev, "Lanes %lu\n", lanes); csi_dev->hw.num_lanes = lanes; return count; @@ -81,7 +81,7 @@ static ssize_t width_store(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret; - dev_info(dev, "width %lu\n", width); + dev_vdbg(dev, "width %lu\n", width); csi_dev->hw.htotal = width; return count; @@ -116,7 +116,7 @@ static ssize_t height_store(struct device *dev, struct device_attribute *attr, if (ret < 0) return ret; - dev_info(dev, "hight %lu\n", height); + dev_vdbg(dev, "hight %lu\n", height); csi_dev->hw.vactive = height; return count; @@ -178,7 +178,7 @@ static ssize_t data_type_store(struct device *dev, return count; } - dev_info(dev, "Data type 0x%lx\n", dt); + dev_vdbg(dev, "Data type 0x%lx\n", dt); csi_dev->ipi_dt = dt; dw_mipi_csi_set_ipi_fmt(csi_dev); @@ -222,7 +222,7 @@ static ssize_t hsa_store(struct device *dev, return count; } - dev_info(dev, "HSA time 0x%lx\n", hsa); + dev_vdbg(dev, "HSA time 0x%lx\n", hsa); csi_dev->hw.hsa = hsa; return count; @@ -263,7 +263,7 @@ static ssize_t hbp_store(struct device *dev, return count; } - dev_info(dev, "HBP time 0x%lx\n", hbp); + dev_vdbg(dev, "HBP time 0x%lx\n", hbp); csi_dev->hw.hbp = hbp; return count; @@ -304,7 +304,7 @@ static ssize_t hsd_store(struct device *dev, return count; } - dev_info(dev, "HSD time 0x%lx\n", hsd); + dev_vdbg(dev, "HSD time 0x%lx\n", hsd); csi_dev->hw.hsd = hsd; return count; @@ -345,7 +345,7 @@ static ssize_t ipi2_hsa_store(struct device *dev, return count; } - dev_info(dev, "HSA time 0x%lx\n", hsa); + dev_vdbg(dev, "HSA time 0x%lx\n", hsa); csi_dev->hw.ipi2_hsa = hsa; return count; @@ -386,7 +386,7 @@ static ssize_t ipi2_hbp_store(struct device *dev, return count; } - dev_info(dev, "HBP time 0x%lx\n", hbp); + dev_vdbg(dev, "HBP time 0x%lx\n", hbp); csi_dev->hw.ipi2_hbp = hbp; return count; @@ -427,7 +427,7 @@ static ssize_t ipi2_hsd_store(struct device *dev, return count; } - dev_info(dev, "HSD time 0x%lx\n", hsd); + dev_vdbg(dev, "HSD time 0x%lx\n", hsd); csi_dev->hw.ipi2_hsd = hsd; return count; @@ -468,7 +468,7 @@ static ssize_t ipi3_hsa_store(struct device *dev, return count; } - dev_info(dev, "HSA time 0x%lx\n", hsa); + dev_vdbg(dev, "HSA time 0x%lx\n", hsa); csi_dev->hw.ipi3_hsa = hsa; return count; @@ -509,7 +509,7 @@ static ssize_t ipi3_hbp_store(struct device *dev, return count; } - dev_info(dev, "HBP time 0x%lx\n", hbp); + dev_vdbg(dev, "HBP time 0x%lx\n", hbp); csi_dev->hw.ipi3_hbp = hbp; return count; @@ -550,7 +550,7 @@ static ssize_t ipi3_hsd_store(struct device *dev, return count; } - dev_info(dev, "HSD time 0x%lx\n", hsd); + dev_vdbg(dev, "HSD time 0x%lx\n", hsd); csi_dev->hw.ipi3_hsd = hsd; return count; @@ -591,7 +591,7 @@ static ssize_t vsa_store(struct device *dev, return count; } - dev_info(dev, "VSA period 0x%lx\n", vsa); + dev_vdbg(dev, "VSA period 0x%lx\n", vsa); csi_dev->hw.vsa = vsa; return count; @@ -632,7 +632,7 @@ static ssize_t vbp_store(struct device *dev, return count; } - dev_info(dev, "VBP period 0x%lx\n", vbp); + dev_vdbg(dev, "VBP period 0x%lx\n", vbp); csi_dev->hw.vbp = vbp; return count; @@ -673,7 +673,7 @@ static ssize_t vfp_store(struct device *dev, return count; } - dev_info(dev, "VFP period 0x%lx\n", vfp); + dev_vdbg(dev, "VFP period 0x%lx\n", vfp); csi_dev->hw.vfp = vfp; return count; @@ -709,7 +709,7 @@ static ssize_t ipi_enable_mask_store(struct device *dev, if (ret < 0) return ret; - dev_info(dev, "enable_mask 0x%lx\n", enable_mask); + dev_vdbg(dev, "enable_mask 0x%lx\n", enable_mask); if (enable_mask & 1) { csi_dev->hw.ipi1_en = true; @@ -783,7 +783,7 @@ static ssize_t virtual_channel_store(struct device *dev, return count; } - dev_info(dev, "Virtual Channel %lu\n", virtual_ch); + dev_vdbg(dev, "Virtual Channel %lu\n", virtual_ch); csi_dev->hw.virtual_ch = virtual_ch; return count; @@ -824,7 +824,7 @@ static ssize_t ipi2_virtual_channel_store(struct device *dev, return count; } - dev_info(dev, "Virtual Channel %lu\n", virtual_ch); + dev_vdbg(dev, "Virtual Channel %lu\n", virtual_ch); csi_dev->hw.ipi2_virtual_ch = virtual_ch; return count; @@ -865,7 +865,7 @@ static ssize_t ipi3_virtual_channel_store(struct device *dev, return count; } - dev_info(dev, "Virtual Channel %lu\n", virtual_ch); + dev_vdbg(dev, "Virtual Channel %lu\n", virtual_ch); csi_dev->hw.ipi3_virtual_ch = virtual_ch; return count; @@ -908,7 +908,7 @@ static ssize_t ipi_color_mode_store(struct device *dev, return count; } - dev_info(dev, "IPI Color mode %lu\n", ipi_color_mode); + dev_vdbg(dev, "IPI Color mode %lu\n", ipi_color_mode); csi_dev->hw.ipi_color_mode = ipi_color_mode; return count; @@ -951,7 +951,7 @@ static ssize_t ipi_auto_flush_store(struct device *dev, return count; } - dev_info(dev, "IPI Auto Flush %lu\n", ipi_auto_flush); + dev_vdbg(dev, "IPI Auto Flush %lu\n", ipi_auto_flush); csi_dev->hw.ipi_auto_flush = ipi_auto_flush; return count; @@ -994,7 +994,7 @@ static ssize_t ipi_timings_mode_store(struct device *dev, return count; } - dev_info(dev, "IPI Color mode %lu\n", ipi_mode); + dev_vdbg(dev, "IPI Color mode %lu\n", ipi_mode); csi_dev->hw.ipi_mode = ipi_mode; return count; @@ -1038,7 +1038,7 @@ static ssize_t output_type_store(struct device *dev, return count; } - dev_info(dev, "IPI Color mode %lu\n", output); + dev_vdbg(dev, "IPI Color mode %lu\n", output); csi_dev->hw.output = output; return count; diff --git a/driver/csi/dw-dphy-plat.c b/driver/csi/dw-dphy-plat.c index 2fee75f..aa429b9 100644 --- a/driver/csi/dw-dphy-plat.c +++ b/driver/csi/dw-dphy-plat.c @@ -92,8 +92,10 @@ int dw_dphy_rx_probe(struct platform_device *pdev, unsigned int dphyglueiftester return -ENOMEM; drvdata = platform_get_drvdata(pdev); - dphy->base_address = drvdata->base + REG_DPHY_OFFSET; drvdata->dphy= dphy; + + dphy->phy_id = drvdata->phy_id; + dphy->base_address = drvdata->base + REG_DPHY_OFFSET; dphy->dphyglueiftester = dphyglueiftester; dphy->sysreg_mipi_csi_ctrl = sysreg_mipi_csi_ctrl; @@ -123,7 +125,7 @@ int dw_dphy_rx_probe(struct platform_device *pdev, unsigned int dphyglueiftester dphy->lp_time = 1000; /* 1000 ns */ dphy->lanes_config = dw_dphy_setup_config(dphy); - dev_info(&dphy->phy->dev, "Probing dphy finished\n"); + dev_vdbg(&dphy->phy->dev, "Probing dphy finished\n"); dw_dphy_create_capabilities_sysfs(pdev); @@ -135,7 +137,7 @@ int dw_dphy_rx_remove(struct platform_device *pdev) struct bm_csi_drvdata *drvdata = platform_get_drvdata(pdev); struct dw_dphy_rx *dphy = drvdata->dphy; - dev_info(&dphy->phy->dev, "phy removed\n"); + dev_vdbg(&dphy->phy->dev, "phy removed\n"); phy_reset(dphy->phy); phy_unregister(&pdev->dev); diff --git a/driver/csi/dw-dphy-rx.c b/driver/csi/dw-dphy-rx.c index 9fc4453..58a923b 100644 --- a/driver/csi/dw-dphy-rx.c +++ b/driver/csi/dw-dphy-rx.c @@ -439,6 +439,14 @@ static int dw_dphy_gen3_12bit_configure(struct dw_dphy_rx *dphy, int abphy_flag) dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0); dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); + + + if (dphy->phy_id == MIPI_A_PHY) { + reg_val = dw_dphy_te_read(dphy, RX_RX_CLKLANE_LANE_6); + reg_val &= ~(3 << 4); + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, reg_val); + } + dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1); udelay(1); dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1); @@ -546,6 +554,12 @@ static int dw_dphy_gen3_12bit_configure(struct dw_dphy_rx *dphy, int abphy_flag) dw_dphy_te_write(dphy, RX_SYS_7, reg_val); } + if (dphy->phy_id == MIPI_A_PHY) { + reg_val = dw_dphy_te_read(dphy, RX_RX_CLKLANE_LANE_6); + reg_val |= (1 << 5); + dw_dphy_te_write(dphy, RX_RX_CLKLANE_LANE_6, reg_val); + } + dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1); udelay(1); dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1); @@ -926,7 +940,7 @@ static int dw_dphy_set_phy_state(struct dw_dphy_rx *dphy, u32 on) if (on) { dw_dphy_configure(dphy); - dev_info(&dphy->phy->dev, + dev_vdbg(&dphy->phy->dev, "HS Code: 0X%x\n", dw_dphy_te_read(dphy, hs_freq)); } else { dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0); @@ -940,7 +954,7 @@ int dw_dphy_power_on(struct phy *phy) { struct dw_dphy_rx *dphy = phy_get_drvdata(phy); - dev_info(&dphy->phy->dev, "DPHY Power ON\n"); + dev_vdbg(&dphy->phy->dev, "DPHY Power ON\n"); bm_info("enter %s\n", __func__); dphy->phy_type = 1; diff --git a/driver/csi/dw-dphy-rx.h b/driver/csi/dw-dphy-rx.h index 9c37da4..4712c7f 100644 --- a/driver/csi/dw-dphy-rx.h +++ b/driver/csi/dw-dphy-rx.h @@ -145,6 +145,12 @@ enum glueiftester { }; //#endif +typedef enum { + MIPI_4LANE_PHY, + MIPI_A_PHY, + MIPI_B_PHY, +} phy_id_e; + /** * struct phy specifies associated phy component * struct cfg to pass mipi dphy specific configurations @@ -167,6 +173,7 @@ struct dw_dphy_rx { u32 lanes_config; u32 dphy_freq; //MBPS u32 phy_type; + phy_id_e phy_id; //csi2_phy, a phy, b phy u32 dphy_gen; u32 dphy_te_len; u32 max_lanes; diff --git a/driver/csi/dw-dphy-sysfs.c b/driver/csi/dw-dphy-sysfs.c index a7e8e18..b7f885c 100644 --- a/driver/csi/dw-dphy-sysfs.c +++ b/driver/csi/dw-dphy-sysfs.c @@ -44,11 +44,11 @@ static ssize_t dphy_freq_store(struct device *dev, return ret; if (freq > 2500) { - dev_info(dev, "Freq must be under 2500 Mhz\n"); + dev_vdbg(dev, "Freq must be under 2500 Mhz\n"); return count; } if (freq < 80) { - dev_info(dev, "Freq must be over 80 Mhz\n"); + dev_vdbg(dev, "Freq must be over 80 Mhz\n"); return count; } diff --git a/driver/csi/dw-mipi-csi.c b/driver/csi/dw-mipi-csi.c index f70b8a2..c7f6d89 100644 --- a/driver/csi/dw-mipi-csi.c +++ b/driver/csi/dw-mipi-csi.c @@ -75,7 +75,7 @@ struct interrupt_type csi_int = { }; #define dw_print(VAR) \ - dev_info(csi_dev->dev, "%s: 0x%x: %X\n", "##VAR##",\ + dev_vdbg(csi_dev->dev, "%s: 0x%x: %X\n", "##VAR##",\ VAR, dw_mipi_csi_read(csi_dev, VAR)) void dw_mipi_csi_write_part(struct dw_csi *dev, u32 address, u32 data, @@ -151,11 +151,15 @@ int dw_mipi_csi_hw_stdby(struct dw_csi *csi_dev) dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY_FATAL, GENMASK(8, 0)); - dw_mipi_csi_write(csi_dev, reg.IPI2_MASK_INT_PHY_FATAL, - GENMASK(8, 0)); + if (csi_dev->hw.ipi2_en) { + dw_mipi_csi_write(csi_dev, reg.IPI2_MASK_INT_PHY_FATAL, + GENMASK(8, 0)); + } - dw_mipi_csi_write(csi_dev, reg.IPI3_MASK_INT_PHY_FATAL, - GENMASK(8, 0)); + if (csi_dev->hw.ipi3_en) { + dw_mipi_csi_write(csi_dev, reg.IPI3_MASK_INT_PHY_FATAL, + GENMASK(8, 0)); + } dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT_FATAL, GENMASK(1, 0)); @@ -300,7 +304,7 @@ void dw_mipi_csi_set_ipi_fmt(struct dw_csi *csi_dev) dw_mipi_csi_write(csi_dev, reg.IPI2_DATA_TYPE, csi_dev->ipi_dt); dw_mipi_csi_write(csi_dev, reg.IPI3_DATA_TYPE, csi_dev->ipi_dt); } - dev_info(dev, "Selected IPI Data Type 0x%X\n", csi_dev->ipi_dt); + dev_vdbg(dev, "Selected IPI Data Type 0x%X\n", csi_dev->ipi_dt); } void dw_mipi_csi_fill_timings(struct dw_csi *dev, uint32_t width, uint32_t height) @@ -349,7 +353,7 @@ void dw_mipi_csi_start(struct dw_csi *csi_dev) struct device *dev = csi_dev->dev; dw_mipi_csi_write(csi_dev, reg.N_LANES, (csi_dev->hw.num_lanes - 1)); - dev_info(dev, "number of lanes: %d\n", csi_dev->hw.num_lanes); + dev_vdbg(dev, "number of lanes: %d\n", csi_dev->hw.num_lanes); /* IPI Related Configuration */ if (csi_dev->hw.output == IPI_OUT || csi_dev->hw.output == BOTH_OUT) { @@ -545,28 +549,35 @@ int dw_mipi_csi_irq_handler(struct dw_csi *csi_dev) struct device *dev = csi_dev->dev; u32 global_int_status, i_sts; unsigned long flags; + struct dw_csi_err_mask *err_mask = &csi_dev->error_mask; + csi_dev->has_error = 1; spin_lock_irqsave(&csi_dev->slock, flags); global_int_status = dw_mipi_csi_read(csi_dev, reg.INTERRUPT); + err_mask->src = global_int_status; if (global_int_status & csi_int.PHY_FATAL) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PHY_FATAL); - dev_err_ratelimited(dev, "int %08X: PHY FATAL: %08X\n", + err_mask->ipi1_phy_fatal_mask = i_sts; + pr_err( "int %08X: PHY FATAL: %08X\n", reg.INT_PHY_FATAL, i_sts); i_sts = dw_mipi_csi_read(csi_dev, reg.IPI2_INT_PHY_FATAL); - dev_err_ratelimited(dev, "int %08X: IPI2 PHY FATAL: %08X\n", + err_mask->ipi2_phy_fatal_mask = i_sts; + pr_err( "int %08X: IPI2 PHY FATAL: %08X\n", reg.IPI2_INT_PHY_FATAL, i_sts); i_sts = dw_mipi_csi_read(csi_dev, reg.IPI3_INT_PHY_FATAL); - dev_err_ratelimited(dev, "int %08X: IPI2 PHY FATAL: %08X\n", + err_mask->ipi3_phy_fatal_mask = i_sts; + pr_err( "int %08X: IPI3 PHY FATAL: %08X\n", reg.IPI3_INT_PHY_FATAL, i_sts); } if (global_int_status & csi_int.PKT_FATAL) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PKT_FATAL); - dev_err_ratelimited(dev, "int %08X: PKT FATAL: %08X\n", + err_mask->pkt_fatal = i_sts; + pr_err( "int %08X: PKT FATAL: %08X\n", reg.INT_PKT_FATAL, i_sts); } @@ -574,13 +585,15 @@ int dw_mipi_csi_irq_handler(struct dw_csi *csi_dev) csi_dev->hw_version_major == 1 && csi_dev->hw_version_minor == 30) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_FRAME_FATAL); - dev_err_ratelimited(dev, "int %08X: FRAME FATAL: %08X\n", + err_mask->frame_fatal = i_sts; + pr_err( "int %08X: FRAME FATAL: %08X\n", reg.INT_FRAME_FATAL, i_sts); } if (global_int_status & csi_int.PHY) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PHY); - dev_err_ratelimited(dev, "int %08X: PHY: %08X\n", + err_mask->phy = i_sts; + pr_err( "int %08X: PHY: %08X\n", reg.INT_PHY, i_sts); } @@ -588,59 +601,81 @@ int dw_mipi_csi_irq_handler(struct dw_csi *csi_dev) csi_dev->hw_version_major == 1 && csi_dev->hw_version_minor <= 30) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PKT); - dev_err_ratelimited(dev, "int %08X: PKT: %08X\n", + pr_err( "int %08X: PKT: %08X\n", reg.INT_PKT, i_sts); } if (global_int_status & csi_int.LINE) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_LINE); - dev_err_ratelimited(dev, "int %08X: LINE: %08X\n", + err_mask->line = i_sts; + pr_err( "int %08X: LINE: %08X\n", reg.INT_LINE, i_sts); } if (global_int_status & csi_int.IPI) { i_sts = dw_mipi_csi_read(csi_dev, reg.INT_IPI); - dev_err_ratelimited(dev, "int %08X: IPI: %08X\n", + err_mask->ipi = i_sts; + pr_err( "int %08X: IPI: %08X\n", + reg.INT_IPI, i_sts); + } + + if (global_int_status & csi_int.IPI2) { + i_sts = dw_mipi_csi_read(csi_dev, reg.IPI2_INT_PHY_FATAL); + err_mask->ipi2 = i_sts; + pr_err( "int %08X: IPI2: %08X\n", + reg.IPI2_INT_PHY_FATAL, i_sts); + } + + if (global_int_status & csi_int.IPI3) { + i_sts = dw_mipi_csi_read(csi_dev, reg.IPI2_INT_PHY_FATAL); + err_mask->ipi3 = i_sts; + pr_err( "int %08X: IPI3: %08X\n", reg.INT_IPI, i_sts); } if (global_int_status & csi_int.BNDRY_FRAME_FATAL) { i_sts = dw_mipi_csi_read(csi_dev, reg.ST_BNDRY_FRAME_FATAL); - dev_err_ratelimited(dev, + err_mask->bndry_frame_fatal = i_sts; + pr_err( "int %08X: ST_BNDRY_FRAME_FATAL: %08X\n", reg.ST_BNDRY_FRAME_FATAL, i_sts); } if (global_int_status & csi_int.SEQ_FRAME_FATAL) { i_sts = dw_mipi_csi_read(csi_dev, reg.ST_SEQ_FRAME_FATAL); - dev_err_ratelimited(dev, + err_mask->seq_frame_fatal = i_sts; + pr_err( "int %08X: ST_SEQ_FRAME_FATAL: %08X\n", reg.ST_SEQ_FRAME_FATAL, i_sts); } if (global_int_status & csi_int.CRC_FRAME_FATAL) { i_sts = dw_mipi_csi_read(csi_dev, reg.ST_CRC_FRAME_FATAL); - dev_err_ratelimited(dev, + err_mask->crc_frame_fatal = i_sts; + pr_err( "int %08X: ST_CRC_FRAME_FATAL: %08X\n", reg.ST_CRC_FRAME_FATAL, i_sts); } if (global_int_status & csi_int.PLD_CRC_FATAL) { i_sts = dw_mipi_csi_read(csi_dev, reg.ST_PLD_CRC_FATAL); - dev_err_ratelimited(dev, + err_mask->pld_crc_fatal = i_sts; + pr_err( "int %08X: ST_PLD_CRC_FATAL: %08X\n", reg.ST_PLD_CRC_FATAL, i_sts); } if (global_int_status & csi_int.DATA_ID) { i_sts = dw_mipi_csi_read(csi_dev, reg.ST_DATA_ID); - dev_err_ratelimited(dev, "int %08X: ST_DATA_ID: %08X\n", + err_mask->data_id = i_sts; + pr_err( "int %08X: ST_DATA_ID: %08X\n", reg.ST_DATA_ID, i_sts); } if (global_int_status & csi_int.ECC_CORRECTED) { i_sts = dw_mipi_csi_read(csi_dev, reg.ST_ECC_CORRECT); - dev_err_ratelimited(dev, "int %08X: ST_ECC_CORRECT: %08X\n", + err_mask->ecc_corrected = i_sts; + pr_err( "int %08X: ST_ECC_CORRECT: %08X\n", reg.ST_ECC_CORRECT, i_sts); } @@ -713,6 +748,8 @@ int dw_mipi_csi_specific_mappings(struct dw_csi *csi_dev) /* interrupts map were changed */ csi_int.LINE = BIT(17); csi_int.IPI = BIT(18); + csi_int.IPI2 = BIT(19); + csi_int.IPI3 = BIT(20); csi_int.BNDRY_FRAME_FATAL = BIT(2); csi_int.SEQ_FRAME_FATAL = BIT(3); csi_int.CRC_FRAME_FATAL = BIT(4); @@ -721,10 +758,10 @@ int dw_mipi_csi_specific_mappings(struct dw_csi *csi_dev) csi_int.ECC_CORRECTED = BIT(7); } else { - dev_info(dev, "Version minor not supported."); + dev_vdbg(dev, "Version minor not supported."); } } else { - dev_info(dev, "Version major not supported."); + dev_vdbg(dev, "Version major not supported."); } return 0; } diff --git a/driver/csi/dw-mipi-csi.h b/driver/csi/dw-mipi-csi.h index be7e503..d5276f6 100644 --- a/driver/csi/dw-mipi-csi.h +++ b/driver/csi/dw-mipi-csi.h @@ -25,6 +25,7 @@ #include #include #include +#include /* Advanced features */ #define IPI_DT_OVERWRITE BIT(0) @@ -144,6 +145,8 @@ struct interrupt_type { u32 PKT; u32 LINE; u32 IPI; + u32 IPI2; + u32 IPI3; u32 BNDRY_FRAME_FATAL; u32 SEQ_FRAME_FATAL; u32 CRC_FRAME_FATAL; @@ -258,6 +261,7 @@ struct csi_data { }; /* Structure to embed device driver information */ + struct dw_csi { //struct v4l2_subdev sd; //struct video_device vdev; @@ -281,6 +285,8 @@ struct dw_csi { u8 index; u8 hw_version_major; u16 hw_version_minor; + int has_error; + struct dw_csi_err_mask error_mask; }; void dw_mipi_csi_reset(struct dw_csi *csi_dev);