Commit 379843df authored by Yi Li's avatar Yi Li Committed by Jason Liu

ENGR00169489-1 Add OV5642 csi camera support for i.mx6 sabre-lite board.

Add OV5642 csi camera support for i.mx6 sabre-lite board
Signed-off-by: default avatarYi Li <R80015@freescale.com>
parent d42e6ea4
......@@ -90,6 +90,8 @@
#define MX6Q_SABRELITE_HOME_KEY IMX_GPIO_NR(2, 4)
#define MX6Q_SABRELITE_VOL_UP_KEY IMX_GPIO_NR(7, 13)
#define MX6Q_SABRELITE_VOL_DOWN_KEY IMX_GPIO_NR(4, 5)
#define MX6Q_SABRELITE_CSI0_RST IMX_GPIO_NR(1, 8)
#define MX6Q_SABRELITE_CSI0_PWN IMX_GPIO_NR(1, 6)
#define MX6Q_SABRELITE_SD3_WP_PADCFG (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
......@@ -212,29 +214,6 @@ static iomux_v3_cfg_t mx6q_sabrelite_pads[] = {
MX6Q_PAD_GPIO_5__I2C3_SCL, /* GPIO1[5] - J7 - Display card */
MX6Q_PAD_GPIO_16__I2C3_SDA, /* GPIO7[11] - J15 - RGB connector */
/* IPU1 Camera */
MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8,
MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9,
MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10,
MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11,
MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN,
MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
MX6Q_PAD_GPIO_6__GPIO_1_6, /* J5 - Camera GP */
MX6Q_PAD_GPIO_8__GPIO_1_8, /* J5 - Camera Reset */
MX6Q_PAD_SD1_DAT0__GPIO_1_16, /* J5 - Camera GP */
MX6Q_PAD_NANDF_D5__GPIO_2_5, /* J16 - MIPI GP */
MX6Q_PAD_NANDF_WP_B__GPIO_6_9, /* J16 - MIPI GP */
/* DISPLAY */
MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* DE */
......@@ -318,6 +297,31 @@ static iomux_v3_cfg_t mx6q_sabrelite_pads[] = {
MX6Q_PAD_NANDF_D7__GPIO_2_7, /* SD4_WP */
};
static iomux_v3_cfg_t mx6q_sabrelite_csi0_sensor_pads[] = {
/* IPU1 Camera */
MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8,
MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9,
MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10,
MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11,
MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN,
MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
MX6Q_PAD_GPIO_6__GPIO_1_6, /* J5 - Camera GP */
MX6Q_PAD_GPIO_8__GPIO_1_8, /* J5 - Camera Reset */
MX6Q_PAD_SD1_DAT0__GPIO_1_16, /* J5 - Camera GP */
MX6Q_PAD_NANDF_D5__GPIO_2_5, /* J16 - MIPI GP */
MX6Q_PAD_NANDF_WP_B__GPIO_6_9, /* J16 - MIPI GP */
};
#define MX6Q_USDHC_PAD_SETTING(id, speed) \
mx6q_sd##id##_##speed##mhz[] = { \
MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
......@@ -550,10 +554,55 @@ static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
},
};
static void mx6q_csi0_io_init(void)
{
mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_csi0_sensor_pads,
ARRAY_SIZE(mx6q_sabrelite_csi0_sensor_pads));
/* Camera power down */
gpio_request(MX6Q_SABRELITE_CSI0_PWN, "cam-pwdn");
gpio_direction_output(MX6Q_SABRELITE_CSI0_PWN, 1);
msleep(1);
gpio_set_value(MX6Q_SABRELITE_CSI0_PWN, 0);
/* Camera reset */
gpio_request(MX6Q_SABRELITE_CSI0_RST, "cam-reset");
gpio_direction_output(MX6Q_SABRELITE_CSI0_RST, 1);
gpio_set_value(MX6Q_SABRELITE_CSI0_RST, 0);
msleep(1);
gpio_set_value(MX6Q_SABRELITE_CSI0_RST, 1);
/* For MX6Q GPR1 bit19 and bit20 meaning:
* Bit19: 0 - Enable mipi to IPU1 CSI0
* virtual channel is fixed to 0
* 1 - Enable parallel interface to IPU1 CSI0
* Bit20: 0 - Enable mipi to IPU2 CSI1
* virtual channel is fixed to 3
* 1 - Enable parallel interface to IPU2 CSI1
* IPU1 CSI1 directly connect to mipi csi2,
* virtual channel is fixed to 1
* IPU2 CSI0 directly connect to mipi csi2,
* virtual channel is fixed to 2
*/
mxc_iomux_set_gpr_register(1, 19, 1, 1);
}
static struct fsl_mxc_camera_platform_data camera_data = {
.mclk = 24000000,
.csi = 0,
.io_init = mx6q_csi0_io_init,
};
static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
{
I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
},
{
I2C_BOARD_INFO("ov5642", 0x3c),
.platform_data = (void *)&camera_data,
},
};
static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
......@@ -771,8 +820,10 @@ static struct fsl_mxc_ldb_platform_data ldb_data = {
static struct imx_ipuv3_platform_data ipu_data[] = {
{
.rev = 4,
.csi_clk[0] = "clko2_clk",
}, {
.rev = 4,
.csi_clk[0] = "clko2_clk",
},
};
......@@ -985,6 +1036,15 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
{
}
static struct mipi_csi2_platform_data mipi_csi2_pdata = {
.ipu_id = 0,
.csi_id = 0,
.v_channel = 0,
.lanes = 2,
.dphy_clk = "mipi_pllref_clk",
.pixel_clk = "emi_clk",
};
/*!
* Board specific initialization.
*/
......@@ -992,6 +1052,9 @@ static void __init mx6_sabrelite_board_init(void)
{
int i;
int ret;
struct clk *clko2;
struct clk *new_parent;
int rate;
mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_pads,
ARRAY_SIZE(mx6q_sabrelite_pads));
......@@ -1009,7 +1072,8 @@ static void __init mx6_sabrelite_board_init(void)
imx6q_add_lcdif(&lcdif_data);
imx6q_add_ldb(&ldb_data);
imx6q_add_v4l2_output(0);
imx6q_add_v4l2_capture(0);
imx6q_add_mipi_csi2(&mipi_csi2_pdata);
imx6q_add_imx_snvs_rtc();
imx6q_add_imx_i2c(0, &mx6q_sabrelite_i2c_data);
......@@ -1071,6 +1135,19 @@ static void __init mx6_sabrelite_board_init(void)
pr_err("failed to request flexcan1-gpios: %d\n", ret);
else
imx6q_add_flexcan0(&mx6q_sabrelite_flexcan0_pdata);
clko2 = clk_get(NULL, "clko2_clk");
if (IS_ERR(clko2))
pr_err("can't get CLKO2 clock.\n");
new_parent = clk_get(NULL, "osc_clk");
if (!IS_ERR(new_parent)) {
clk_set_parent(clko2, new_parent);
clk_put(new_parent);
}
rate = clk_round_rate(clko2, 24000000);
clk_set_rate(clko2, rate);
clk_enable(clko2);
}
extern void __iomem *twd_base;
......
/*
* Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
......@@ -4655,6 +4655,100 @@ static unsigned long _clk_clko_round_rate(struct clk *clk,
return parent_rate / div;
}
static int _clk_clko2_set_parent(struct clk *clk, struct clk *parent)
{
u32 sel, reg;
if (parent == &mmdc_ch0_axi_clk[0])
sel = 0;
else if (parent == &mmdc_ch1_axi_clk[0])
sel = 1;
else if (parent == &usdhc4_clk)
sel = 2;
else if (parent == &usdhc1_clk)
sel = 3;
else if (parent == &gpu2d_axi_clk)
sel = 4;
else if (parent == &ecspi_clk[0])
sel = 6;
else if (parent == &gpu3d_axi_clk)
sel = 7;
else if (parent == &usdhc3_clk)
sel = 8;
else if (parent == &pcie_clk[0])
sel = 9;
else if (parent == &ipu1_clk)
sel = 11;
else if (parent == &ipu2_clk)
sel = 12;
else if (parent == &vdo_axi_clk)
sel = 13;
else if (parent == &osc_clk)
sel = 14;
else if (parent == &gpu2d_core_clk[0])
sel = 15;
else if (parent == &gpu3d_core_clk[0])
sel = 16;
else if (parent == &usdhc2_clk)
sel = 17;
else if (parent == &ssi1_clk)
sel = 18;
else if (parent == &ssi2_clk)
sel = 19;
else if (parent == &ssi3_clk)
sel = 20;
else if (parent == &gpu3d_shader_clk)
sel = 21;
else if (parent == &can_clk_root)
sel = 23;
else if (parent == &ldb_di0_clk)
sel = 24;
else if (parent == &ldb_di1_clk)
sel = 25;
else if (parent == &esai_clk)
sel = 26;
else if (parent == &uart_clk[0])
sel = 28;
else if (parent == &spdif0_clk[0])
sel = 29;
else if (parent == &hsi_tx_clk[0])
sel = 31;
else
return -EINVAL;
reg = __raw_readl(MXC_CCM_CCOSR);
reg &= ~MXC_CCM_CCOSR_CKO2_SEL_MASK;
reg |= sel << MXC_CCM_CCOSR_CKO2_SEL_OFFSET;
__raw_writel(reg, MXC_CCM_CCOSR);
return 0;
}
static unsigned long _clk_clko2_get_rate(struct clk *clk)
{
u32 reg = __raw_readl(MXC_CCM_CCOSR);
u32 div = ((reg & MXC_CCM_CCOSR_CKO2_DIV_MASK) >>
MXC_CCM_CCOSR_CKO2_DIV_OFFSET) + 1;
return clk_get_rate(clk->parent) / div;
}
static int _clk_clko2_set_rate(struct clk *clk, unsigned long rate)
{
u32 reg;
u32 parent_rate = clk_get_rate(clk->parent);
u32 div = parent_rate / rate;
if (div == 0)
div++;
if (((parent_rate / div) != rate) || (div > 8))
return -EINVAL;
reg = __raw_readl(MXC_CCM_CCOSR);
reg &= ~MXC_CCM_CCOSR_CKO2_DIV_MASK;
reg |= (div - 1) << MXC_CCM_CCOSR_CKO2_DIV_OFFSET;
__raw_writel(reg, MXC_CCM_CCOSR);
return 0;
}
static struct clk clko_clk = {
__INIT_CLK_DEBUG(clko_clk)
.parent = &pll2_528_bus_main_clk,
......@@ -4668,6 +4762,19 @@ static struct clk clko_clk = {
.round_rate = _clk_clko_round_rate,
};
static struct clk clko2_clk = {
__INIT_CLK_DEBUG(clko2_clk)
.parent = &usdhc4_clk,
.enable = _clk_enable1,
.enable_reg = MXC_CCM_CCOSR,
.enable_shift = MXC_CCM_CCOSR_CKO2_EN_OFFSET,
.disable = _clk_disable1,
.set_parent = _clk_clko2_set_parent,
.set_rate = _clk_clko2_set_rate,
.get_rate = _clk_clko2_get_rate,
.round_rate = _clk_clko_round_rate,
};
static struct clk perfmon0_clk = {
__INIT_CLK_DEBUG(perfmon0_clk)
.parent = &mmdc_ch0_axi_clk[0],
......@@ -4820,6 +4927,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, NULL, aips_tz2_clk),
_REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
_REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
_REGISTER_CLOCK(NULL, "clko2_clk", clko2_clk),
_REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
_REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
_REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
......@@ -4909,6 +5017,10 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
clk_set_parent(&gpu3d_core_clk[0], &mmdc_ch0_axi_clk[0]);
clk_set_rate(&gpu3d_core_clk[0], 528000000);
/* PCLK camera - J5 */
clk_set_parent(&clko2_clk, &osc_clk);
clk_set_rate(&clko2_clk, 2400000);
/*
* FIXME: asrc needs to use asrc_serial(spdif1) clock to do sample
* rate convertion and this clock frequency can not be too high, set
......
/*
* Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
......@@ -448,7 +448,7 @@
#define MXC_CCM_CIMR_MASK_LRF_PLL (1)
/* Define the bits in register CCOSR */
#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (1 << 24)
#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (24)
#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment