From 2ae81c23d9e56616aa2367e3f56ceae4ed6a37c1 Mon Sep 17 00:00:00 2001 From: Jason Chen Date: Mon, 5 Dec 2011 17:54:54 +0800 Subject: imx6q-sabrelite: add mxc hdmi and related i2c dt support Signed-off-by: Jason Chen --- arch/arm/boot/dts/imx6q-sabrelite.dts | 15 ++++++++++ arch/arm/boot/dts/imx6q.dtsi | 6 ++++ arch/arm/mach-imx/clock-imx6q.c | 1 + drivers/i2c/busses/i2c-imx.c | 1 + drivers/mfd/mxc-hdmi-core.c | 55 +++++++++++++++++++++++++++++++++-- drivers/video/mxc_hdmi.c | 9 +++++- 6 files changed, 84 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts index 3011d3d2859..91c56186cb2 100644 --- a/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/arch/arm/boot/dts/imx6q-sabrelite.dts @@ -46,6 +46,21 @@ uart1: uart@021e8000 { /* UART2 */ status = "okay"; }; + + i2c@021a4000 { /* I2C2 */ + status = "okay"; + clock-frequency = <400000>; + + ddc: ddc@50 { + compatible = "fsl,imx6q-hdmi-ddc"; + reg = <0x50>; + }; + }; + }; + + hdmi@0x00120000 { /* HDMI */ + ipu = <0>; + di = <0>; }; }; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 5d912e44a1c..dc393c1e75f 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -572,6 +572,12 @@ }; }; + hdmi@0x00120000 { /* HDMI */ + compatible = "fsl,imx6q-hdmi-core"; + reg = <0x00120000 0x9000>; + interrupts = <0 115 0x04 0 116 0x04>; + }; + ipu@0x02400000 { /* IPU1 */ compatible = "fsl,ipuv3"; reg = <0x02400000 0x400000>; diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c index 86e7afbd9ea..f952b45d31d 100644 --- a/arch/arm/mach-imx/clock-imx6q.c +++ b/arch/arm/mach-imx/clock-imx6q.c @@ -1917,6 +1917,7 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK(NULL, "ipu1_di1_clk", ipu1_di1_clk), _REGISTER_CLOCK(NULL, "ipu2_di0_clk", ipu2_di0_clk), _REGISTER_CLOCK(NULL, "ipu2_di1_clk", ipu2_di1_clk), + _REGISTER_CLOCK(NULL, "hdmi_iahb_clk", hdmi_iahb_clk), }; int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 58832e578ff..08432ce7c67 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -130,6 +130,7 @@ struct imx_i2c_struct { static const struct of_device_id i2c_imx_dt_ids[] = { { .compatible = "fsl,imx1-i2c", }, + { .compatible = "fsl,imx6q-i2c", }, { /* sentinel */ } }; diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c index 48cc57cc1b8..1ecdc0d9d8e 100644 --- a/drivers/mfd/mxc-hdmi-core.c +++ b/drivers/mfd/mxc-hdmi-core.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include @@ -391,12 +393,40 @@ void hdmi_set_sample_rate(unsigned int rate) hdmi_set_clk_regenerator(); } +static void hdmi_init(int ipu_id, int disp_id) +{ + int hdmi_mux_setting; + + if ((ipu_id > 1) || (ipu_id < 0)) { + printk(KERN_ERR"Invalid IPU select for HDMI: %d. Set to 0\n", + ipu_id); + ipu_id = 0; + } + + if ((disp_id > 1) || (disp_id < 0)) { + printk(KERN_ERR"Invalid DI select for HDMI: %d. Set to 0\n", + disp_id); + disp_id = 0; + } + + /* Configure the connection between IPU1/2 and HDMI */ + hdmi_mux_setting = 2*ipu_id + disp_id; + + /* GPR3, bits 2-3 = HDMI_MUX_CTL */ + /*mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);*/ +} + +static struct fsl_mxc_hdmi_platform_data hdmi_vdata = { + .init = hdmi_init, +}; + static int mxc_hdmi_core_probe(struct platform_device *pdev) { struct fsl_mxc_hdmi_core_platform_data *pdata = pdev->dev.platform_data; struct mxc_hdmi_data *hdmi_data; struct resource *res; int ret = 0; + struct platform_device_info pdevinfo_hdmi_v; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -468,8 +498,13 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev) pr_debug("\n%s hdmi hw base = 0x%08x\n\n", __func__, (int)res->start); - mxc_hdmi_ipu_id = pdata->ipu_id; - mxc_hdmi_disp_id = pdata->disp_id; + if (pdata) { + mxc_hdmi_ipu_id = pdata->ipu_id; + mxc_hdmi_disp_id = pdata->disp_id; + } else { + of_property_read_u32(pdev->dev.of_node, "ipu", &mxc_hdmi_ipu_id); + of_property_read_u32(pdev->dev.of_node, "di", &mxc_hdmi_disp_id); + } initialize_hdmi_ih_mutes(); @@ -480,6 +515,16 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev) /* Replace platform data coming in with a local struct */ platform_set_drvdata(pdev, hdmi_data); + /* register hdmi video */ + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + pdevinfo_hdmi_v.name = "mxc_hdmi"; + pdevinfo_hdmi_v.res = res; + pdevinfo_hdmi_v.num_res = 1; + pdevinfo_hdmi_v.data = &hdmi_vdata; + pdevinfo_hdmi_v.size_data = sizeof(hdmi_vdata); + pdevinfo_hdmi_v.dma_mask = DMA_BIT_MASK(32); + platform_device_register_full(&pdevinfo_hdmi_v); + return ret; eirq: @@ -511,10 +556,16 @@ static int __exit mxc_hdmi_core_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id mxc_hdmi_core_dt_ids[] = { + { .compatible = "fsl,imx6q-hdmi-core", }, + { /* sentinel */ } +}; + static struct platform_driver mxc_hdmi_core_driver = { .driver = { .name = "mxc_hdmi_core", .owner = THIS_MODULE, + .of_match_table = mxc_hdmi_core_dt_ids, }, .remove = __exit_p(mxc_hdmi_core_remove), }; diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c index 0298c243b1a..924264c32e2 100644 --- a/drivers/video/mxc_hdmi.c +++ b/drivers/video/mxc_hdmi.c @@ -1580,7 +1580,8 @@ static int mxc_hdmi_setup(struct mxc_hdmi *hdmi) hdmi_tx_hdcp_config(hdmi); hdmi_phy_init(hdmi, TRUE); hdmi_video_force_output(hdmi, FALSE); - hdmi_set_clk_regenerator(); + /*FIXME: audio CTS/N should be set after ipu display timming finish */ + /*hdmi_set_clk_regenerator();*/ return 0; } @@ -1943,9 +1944,15 @@ static const struct i2c_device_id mxc_hdmi_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id); +static const struct of_device_id mxc_hdmi_ddc_dt_ids[] = { + { .compatible = "fsl,imx6q-hdmi-ddc", }, + { /* sentinel */ } +}; + static struct i2c_driver mxc_hdmi_i2c_driver = { .driver = { .name = "mxc_hdmi_i2c", + .of_match_table = mxc_hdmi_ddc_dt_ids, }, .probe = mxc_hdmi_i2c_probe, .remove = mxc_hdmi_i2c_remove, -- cgit v1.2.3