#include <mach/io_dpd.h>
#include "mc_common.h"
-#include "../vi/vi.h"
+#include "vi/vi.h"
+#include "mipical/mipi_cal.h"
#define FRAMERATE 30
#define BPP_MEM 2
ret = tegra_channel_set_stream(chan, true);
if (ret < 0)
goto error_set_stream;
- /*
- nvhost_module_enable_clk(chan->vi->dev);
tegra_mipi_bias_pad_enable();
mutex_lock(&chan->vi->mipical_lock);
- tegra_channel_mipi_cal(chan, 1);
+ csi_mipi_cal(chan, 1);
mutex_unlock(&chan->vi->mipical_lock);
- nvhost_module_disable_clk(chan->vi->dev);*/
return ret;
}
chan->capture_state = CAPTURE_IDLE;
if (!chan->vi->pg_mode) {
tegra_channel_set_stream(chan, false);
media_entity_pipeline_stop(&chan->video.entity);
+ tegra_mipi_bias_pad_disable();
}
if (!chan->bypass)
/* maximum of 4 lanes are present per CSI block */
chan->csibase[idx] = vi->iomem +
TEGRA_VI_CSI_BASE(chan->port[idx]);
- set_csi_portinfo(vi->csi, chan->port[idx], numlanes);
}
/* based on gang mode valid ports will be updated - set default to 1 */
chan->valid_ports = chan->total_ports ? 1 : 0;
chan->vi = vi;
//chan->fops = vi->vi->data->channel_fops;
- //tegra_channel_csi_init(vi, index);
+ tegra_channel_csi_init(vi, index);
chan->width_align = TEGRA_WIDTH_ALIGNMENT;
chan->stride_align = TEGRA_STRIDE_ALIGNMENT;
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <media/media-entity.h>
#include <media/v4l2-async.h>
#include "dev.h"
#include "vi/vi.h"
#include "csi/csi.h"
+#include "camera/mc_common.h"
+#include "mipical/mipi_cal.h"
+#include "linux/nvhost.h"
+#include "nvcsi/nvcsi.h"
void set_csi_portinfo(struct tegra_csi_device *csi,
unsigned int port, unsigned int numlanes)
}
EXPORT_SYMBOL(tegra_csi_stop_streaming);
+static struct tegra_csi_device *get_csi(void)
+{
+ struct device_node *np;
+ struct platform_device *dev;
+ struct nvhost_device_data *pdata;
+
+ np = of_find_node_by_name(NULL, "nvcsi");
+ if (!np) {
+ pr_err("%s: Can not find nvcsi node\n", __func__);
+ return NULL;
+ }
+ dev = of_find_device_by_node(np);
+ if (!dev) {
+ pr_err("%s:Can not find device\n", __func__);
+ return NULL;
+ }
+ pdata = platform_get_drvdata(dev);
+ if (!pdata) {
+ pr_err("%s:Can not find driver\n", __func__);
+ return NULL;
+ }
+ return &((struct nvcsi *)pdata->private_data)->csi;
+}
+
+int csi_mipi_cal(struct tegra_channel *chan, char is_bypass)
+{
+ unsigned int lanes, cur_lanes;
+ unsigned int cila, cilb;
+ struct tegra_csi_device *csi;
+ int j;
+
+ csi = get_csi();
+ if (!csi)
+ return -EINVAL;
+
+ lanes = 0;
+
+ if (chan->numlanes == 2 && chan->total_ports == 1) {
+ cila = (0x01 << E_INPUT_LP_IO0_SHIFT) |
+ (0x01 << E_INPUT_LP_IO1_SHIFT) |
+ (0x01 << E_INPUT_LP_CLK) |
+ (0x00 << PD_CLK) |
+ (0x00 << PD_IO0) |
+ (0x00 << PD_IO1);
+ cilb = cila;
+ switch (chan->port[0]) {
+ case PORT_A:
+ lanes = CSIA;
+ host1x_writel(csi->pdev, NVCSI_PHY_0_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ break;
+ case PORT_B:
+ lanes = CSIB;
+ host1x_writel(csi->pdev, NVCSI_PHY_0_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ case PORT_C:
+ lanes = CSIC;
+ host1x_writel(csi->pdev, NVCSI_PHY_1_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ break;
+ case PORT_D:
+ lanes = CSID;
+ host1x_writel(csi->pdev, NVCSI_PHY_1_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ case PORT_E:
+ lanes = CSIE;
+ host1x_writel(csi->pdev, NVCSI_PHY_2_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ break;
+ case PORT_F:
+ lanes = CSIF;
+ host1x_writel(csi->pdev, NVCSI_PHY_2_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ }
+ } else if (chan->numlanes == 4 && chan->total_ports == 1) {
+ cila = (0x01 << E_INPUT_LP_IO0_SHIFT) |
+ (0x01 << E_INPUT_LP_IO1_SHIFT) |
+ (0x01 << E_INPUT_LP_CLK) |
+ (0x00 << PD_CLK) |
+ (0x00 << PD_IO0) |
+ (0x00 << PD_IO1);
+ cilb = (0x01 << E_INPUT_LP_IO0_SHIFT) |
+ (0x01 << E_INPUT_LP_IO1_SHIFT) |
+ (0x01 << PD_CLK) |
+ (0x00 << PD_IO0) |
+ (0x00 << PD_IO1);
+ switch (chan->port[0]) {
+ case PORT_A:
+ case PORT_B:
+ lanes = CSIA|CSIB;
+ host1x_writel(csi->pdev, NVCSI_PHY_0_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ host1x_writel(csi->pdev, NVCSI_PHY_0_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ case PORT_C:
+ case PORT_D:
+ lanes = CSIC|CSID;
+ host1x_writel(csi->pdev, NVCSI_PHY_1_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ host1x_writel(csi->pdev, NVCSI_PHY_1_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ case PORT_E:
+ case PORT_F:
+ lanes = CSIE|CSIF;
+ host1x_writel(csi->pdev, NVCSI_PHY_2_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ host1x_writel(csi->pdev, NVCSI_PHY_2_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ }
+ } else if (chan->numlanes == 8) {
+ cila = (0x01 << E_INPUT_LP_IO0_SHIFT) |
+ (0x01 << E_INPUT_LP_IO1_SHIFT) |
+ (0x01 << E_INPUT_LP_CLK) |
+ (0x00 << PD_CLK) |
+ (0x00 << PD_IO0) |
+ (0x00 << PD_IO1);
+ cilb = (0x01 << E_INPUT_LP_IO0_SHIFT) |
+ (0x01 << E_INPUT_LP_IO1_SHIFT) |
+ (0x01 << PD_CLK) |
+ (0x00 << PD_IO0) |
+ (0x00 << PD_IO1);
+ cur_lanes = 0;
+ for (j = 0; j < chan->valid_ports; ++j) {
+ switch (chan->port[j]) {
+ case PORT_A:
+ case PORT_B:
+ cur_lanes = CSIA|CSIB;
+ host1x_writel(csi->pdev, NVCSI_PHY_0_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ host1x_writel(csi->pdev, NVCSI_PHY_0_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ case PORT_C:
+ case PORT_D:
+ cur_lanes = CSIC|CSID;
+ host1x_writel(csi->pdev, NVCSI_PHY_1_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ host1x_writel(csi->pdev, NVCSI_PHY_1_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ case PORT_E:
+ case PORT_F:
+ cur_lanes = CSIE|CSIF;
+ host1x_writel(csi->pdev, NVCSI_PHY_2_BASE +
+ NVCSI_CIL_A_BASE + PAD_CONFIG_0,
+ cila);
+ host1x_writel(csi->pdev, NVCSI_PHY_2_BASE +
+ NVCSI_CIL_B_BASE + PAD_CONFIG_0,
+ cilb);
+ break;
+ default:
+ dev_err(csi->dev, "csi_port number: %d",
+ chan->port[0]);
+ break;
+ }
+ lanes |= cur_lanes;
+ }
+ }
+
+ if (!lanes) {
+ dev_err(csi->dev, "Selected no CSI lane, cannot do calibration");
+ return -EINVAL;
+ }
+ return tegra_mipi_calibration(lanes);
+}
+EXPORT_SYMBOL(csi_mipi_cal);
+
static int tegra_csi_s_stream(struct v4l2_subdev *subdev, int enable)
{
- struct tegra_csi_device *csi = to_csi(subdev);
+ struct tegra_csi_device *csi;
struct tegra_channel *chan;
int index;
+ csi = to_csi(subdev);
+ if (!csi)
+ return -EINVAL;
+ if (enable)
+ nvhost_module_busy(csi->pdev);
+ else
+ nvhost_module_idle(csi->pdev);
return 0;
if (csi->pg_mode)
int ret, i;
csi->dev = &pdev->dev;
-
+ csi->pdev = pdev;
if (csi->pg_mode)
ret = tegra_tpg_csi_parse_data(csi, pdev);
else
#include <media/v4l2-async.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
+#include <linux/platform_device.h>
#include <media/camera_common.h>
#include "../camera/registers.h"
-#include <linux/platform_device.h>
-
+#include "../camera/mc_common.h"
+
+#define NVCSI_PHY_0_BASE 0x18000
+#define NVCSI_CIL_PHY_CTRL_0 0x0
+#define CFG_PHY_MODE 0x1
+#define CFG_PHY_MODE_SHIFT 0
+#define NVCSI_CIL_CONFIG_0 0x4
+#define DATA_LANE_A 0x7
+#define DATA_LANE_A_SHIFT 0
+#define DATA_LANE_B 0x7
+#define DATA_LANE_B_SHIFT 8
+#define NVCSI_CIL_CLKEN_OVERRIDE_CTRL_0 0x8
+#define NVCSI_CIL_PAD_CONFIG_0 0xc
+#define NVCSI_CIL_LANE_SWIZZLE_CTRL_0 0x10
+
+#define NVCSI_CIL_A_BASE 0x18
+#define SW_RESET_0 0x0
+#define CLKEN_OVERRIDE_CTRL_0 0x4
+#define PAD_CONFIG_0 0x8
+#define E_INPUT_LP_IO1_SHIFT 22
+#define E_INPUT_LP_IO0_SHIFT 21
+#define E_INPUT_LP_CLK 20
+#define PD_CLK 18
+#define PD_IO1 17
+#define PD_IO0 16
+#define CLK_DESKEW_CTRL_0 0x14
+#define DATA_DESKEW_CTRL_0 0x18
+#define POLARITY_SWIZZLE_CTRL_0 0x40
+#define CONTROL_0 0x44
+#define NVCSI_CIL_B_BASE 0x7c
+
+#define NVCSI_PHY_1_BASE 0x28000
+#define NVCSI_PHY_2_BASE 0x38000
enum tegra_csi_port_num {
PORT_A = 0,
CAMERA_GANG_B_T
};
+struct tegra_channel;
+
struct tegra_csi_port {
void __iomem *pixel_parser;
void __iomem *cil;
struct v4l2_subdev subdev;
struct vi *vi;
struct device *dev;
+ struct platform_device *pdev;
void __iomem *iomem[3];
struct clk *clk;
struct clk *tpg_clk;
int tegra_csi_media_controller_init(struct tegra_csi_device *csi,
struct platform_device *pdev);
int tegra_csi_media_controller_remove(struct tegra_csi_device *csi);
+int csi_mipi_cal(struct tegra_channel *chan, char is_bypass);
#endif