mirror of
https://github.com/thead-yocto-mirror/baremetal-drivers
synced 2026-06-21 17:22:26 +02:00
Compare commits
3 Commits
Linux_SDK_
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65bf77d5b5 | ||
|
|
a83488e9c5 | ||
|
|
34b5899c3c |
@@ -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, ...)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
|
||||
#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);
|
||||
@@ -80,16 +82,9 @@ static int bm_csi_runtime_suspend(struct device *dev)
|
||||
clk_disable_unprepare(pdriver_dev->pixclk);
|
||||
}
|
||||
|
||||
if (pdriver_dev->cfg_clk0!= NULL) {
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk0);
|
||||
}
|
||||
|
||||
if (pdriver_dev->cfg_clk1!= NULL) {
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk1);
|
||||
}
|
||||
|
||||
if (pdriver_dev->cfg_clk2!= NULL) {
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk2);
|
||||
if (pdriver_dev->cfg_clk!= NULL) {
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk);
|
||||
pr_info("%s, %d, cfg clk disable\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
pr_info("exit %s\n", __func__);
|
||||
@@ -99,12 +94,12 @@ 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);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "could not prepare or enable csi pclk\n");
|
||||
pr_err("could not prepare or enable csi pclk\n");
|
||||
clk_disable_unprepare(pdriver_dev->pclk);
|
||||
return -1;
|
||||
}
|
||||
@@ -113,35 +108,18 @@ static int bm_csi_runtime_resume(struct device *dev)
|
||||
if (pdriver_dev->pixclk!= NULL) {
|
||||
ret = clk_prepare_enable(pdriver_dev->pixclk);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "could not prepare or enable pixclk\n");
|
||||
pr_err("could not prepare or enable pixclk\n");
|
||||
clk_disable_unprepare(pdriver_dev->pixclk);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdriver_dev->cfg_clk0 != NULL) {
|
||||
ret = clk_prepare_enable(pdriver_dev->cfg_clk0);
|
||||
if (pdriver_dev->cfg_clk != NULL) {
|
||||
ret = clk_prepare_enable(pdriver_dev->cfg_clk);
|
||||
pr_info("%s, %d, cfg clk enable\n", __func__, __LINE__);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "could not prepare or enable cfg_clk0\n");
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdriver_dev->cfg_clk1 != NULL) {
|
||||
ret = clk_prepare_enable(pdriver_dev->cfg_clk1);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "could not prepare or enable cfg_clk1\n");
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdriver_dev->cfg_clk2 != NULL) {
|
||||
ret = clk_prepare_enable(pdriver_dev->cfg_clk2);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "could not prepare or enable cfg_clk2\n");
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk2);
|
||||
pr_err("could not prepare or enable cfg_clk\n");
|
||||
clk_disable_unprepare(pdriver_dev->cfg_clk);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -161,16 +139,29 @@ 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");
|
||||
if (pm_runtime_get_sync(dev)) {
|
||||
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));
|
||||
|
||||
pr_info("%s, %d, drvdata = %p\n", __func__, __LINE__, drvdata);
|
||||
pr_info("%s, %d, dev = %p\n", __func__, __LINE__, dev);
|
||||
|
||||
bm_info("open mipi-csi dev\n");
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret) {
|
||||
pr_err("%s, %d runtime get sync err, %d\n", __func__, __LINE__, ret);
|
||||
ret = bm_csi_runtime_resume(dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pr_err("fail to resume csi %s %d\n", __func__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -196,6 +187,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 +247,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:
|
||||
@@ -272,10 +269,9 @@ static int bm_csi_release(struct inode * inode, struct file * file)
|
||||
|
||||
bm_info("enter %s\n", __func__);
|
||||
|
||||
drvdata = container_of(inode->i_cdev, struct bm_csi_drvdata, cdev);
|
||||
file->private_data = drvdata;
|
||||
drvdata = file->private_data;
|
||||
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__);
|
||||
@@ -283,7 +279,8 @@ static int bm_csi_release(struct inode * inode, struct file * file)
|
||||
|
||||
ret = pm_runtime_put_sync(dev);
|
||||
if (ret) {
|
||||
pr_info("fail to resume csi %s %d\n", __func__, __LINE__);
|
||||
pr_err("%s %d, fail to resume csi, %d\n", __func__, __LINE__, ret);
|
||||
bm_csi_runtime_suspend(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -311,6 +308,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 +324,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);
|
||||
@@ -352,25 +382,15 @@ static int bm_csi_probe(struct platform_device *pdev)
|
||||
drvdata->pixclk = NULL;
|
||||
}
|
||||
|
||||
drvdata->cfg_clk0 = devm_clk_get(&pdev->dev, "cfg_clk0");
|
||||
if (IS_ERR(drvdata->cfg_clk0)) {
|
||||
dev_err(&pdev->dev, "failed to get cfg_clk0");
|
||||
drvdata->cfg_clk0 = NULL;
|
||||
}
|
||||
|
||||
drvdata->cfg_clk1 = devm_clk_get(&pdev->dev, "cfg_clk1");
|
||||
if (IS_ERR(drvdata->cfg_clk1)) {
|
||||
dev_err(&pdev->dev, "failed to get cfg_clk1");
|
||||
drvdata->cfg_clk1 = NULL;
|
||||
}
|
||||
|
||||
drvdata->cfg_clk2 = devm_clk_get(&pdev->dev, "cfg_clk2");
|
||||
if (IS_ERR(drvdata->cfg_clk2)) {
|
||||
dev_err(&pdev->dev, "failed to get cfg_clk2");
|
||||
drvdata->cfg_clk2 = NULL;
|
||||
drvdata->cfg_clk = devm_clk_get(&pdev->dev, "cfg_clk");
|
||||
if (IS_ERR(drvdata->cfg_clk)) {
|
||||
dev_err(&pdev->dev, "failed to get cfg_clk");
|
||||
drvdata->cfg_clk = NULL;
|
||||
}
|
||||
|
||||
pr_info("%s, %d, drvdata = %p\n", __func__, __LINE__, drvdata);
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
pr_info("%s, %d, dev = %p\n", __func__, __LINE__, &pdev->dev);
|
||||
|
||||
if (pdev->id == 0) {
|
||||
if (bm_driver_major == 0) {
|
||||
@@ -420,18 +440,18 @@ 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);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
if (ret < 0) {
|
||||
pr_err("%s, %d, fail to resume csi, %d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
|
||||
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_put_sync(&pdev->dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "fail to resume csi\n");
|
||||
}
|
||||
|
||||
ret = bm_csi_runtime_suspend(&pdev->dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "fail to suspend csi\n");
|
||||
pr_err("%s, %d, fail to suspend csi, %d\n", __func__, __LINE__, ret);
|
||||
}
|
||||
|
||||
device_register_index++;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -31,10 +34,10 @@ struct bm_csi_drvdata {
|
||||
int irq_num;
|
||||
struct clk *pclk;
|
||||
struct clk *pixclk;
|
||||
struct clk *cfg_clk0;
|
||||
struct clk *cfg_clk1;
|
||||
struct clk *cfg_clk2;
|
||||
struct clk *cfg_clk;
|
||||
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 +47,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 +61,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);
|
||||
|
||||
@@ -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_*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/wait.h>
|
||||
#include <dw-mipi-csi-pltfrm.h>
|
||||
#include <bm_csi_ioctl.h>
|
||||
|
||||
/* 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);
|
||||
|
||||
Reference in New Issue
Block a user