mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: barebox@lists.infradead.org
Subject: [PATCH 19/29] ARM: i.MX6: Add video clocks
Date: Fri, 14 Mar 2014 15:32:39 +0100	[thread overview]
Message-ID: <1394807569-23620-20-git-send-email-s.hauer@pengutronix.de> (raw)
In-Reply-To: <1394807569-23620-1-git-send-email-s.hauer@pengutronix.de>

This adds the IPU, LVDS and HDMI clocks. As these are many, depend
on the IPU driver being compiled in.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/clk-imx6.c               | 153 ++++++++++++++++++++++++++++-
 arch/arm/mach-imx/clk.h                    |   6 ++
 arch/arm/mach-imx/include/mach/imx6-regs.h |   3 +
 3 files changed, 158 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c
index db16bb5..518fc00 100644
--- a/arch/arm/mach-imx/clk-imx6.c
+++ b/arch/arm/mach-imx/clk-imx6.c
@@ -19,6 +19,8 @@
 #include <linux/clkdev.h>
 #include <linux/err.h>
 #include <mach/imx6-regs.h>
+#include <mach/revision.h>
+#include <mach/imx6.h>
 
 #include "clk.h"
 
@@ -84,8 +86,10 @@ enum mx6q_clks {
 	usdhc4, vdo_axi, vpu_axi, cko1, pll1_sys, pll2_bus, pll3_usb_otg,
 	pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
 	ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
-	sata_ref, pcie_ref, sata_ref_100m, pcie_ref_125m, enet_ref,
-	clk_max
+	sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
+	usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow,
+	spdif, cko2_sel, cko2_podf, cko2, cko, vdoa, pll4_audio_div,
+	lvds1_sel, lvds2_sel, lvds1_gate, lvds2_gate, clk_max
 };
 
 static struct clk *clks[clk_max];
@@ -171,6 +175,62 @@ static const char *cko1_sels[] = {
 	"pll4_audio",
 };
 
+static const char *ipu_sels[] = {
+	"mmdc_ch0_axi_podf",
+	"pll2_pfd2_396m",
+	"pll3_120m",
+	"pll3_pfd1_540m",
+};
+
+static const char *ldb_di_sels[] = {
+	"pll5_video_div",
+	"pll2_pfd0_352m",
+	"pll2_pfd2_396m",
+	"mmdc_ch1_axi_podf",
+	"pll3_usb_otg",
+};
+
+static const char *ipu_di_pre_sels[] = {
+	"mmdc_ch0_axi",
+	"pll3_usb_otg",
+	"pll5_video_div",
+	"pll2_pfd0_352m",
+	"pll2_pfd2_396m",
+	"pll3_pfd1_540m",
+};
+
+static const char *ipu1_di0_sels[] = {
+	"ipu1_di0_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *ipu1_di1_sels[] = {
+	"ipu1_di1_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *ipu2_di0_sels[] = {
+	"ipu2_di0_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
+static const char *ipu2_di1_sels[] = {
+	"ipu2_di1_pre",
+	"dummy",
+	"dummy",
+	"ldb_di0_podf",
+	"ldb_di1_podf",
+};
+
 static struct clk_div_table clk_enet_ref_table[] = {
 	{ .val = 0, .div = 20, },
 	{ .val = 1, .div = 10, },
@@ -179,6 +239,86 @@ static struct clk_div_table clk_enet_ref_table[] = {
 	{ },
 };
 
+static struct clk_div_table post_div_table[] = {
+	{ .val = 2, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 0, .div = 4, },
+	{ /* sentinel */ }
+};
+
+static struct clk_div_table video_div_table[] = {
+	{ .val = 0, .div = 1, },
+	{ .val = 1, .div = 2, },
+	{ .val = 2, .div = 1, },
+	{ .val = 3, .div = 4, },
+	{ /* sentinel */ }
+};
+
+static void imx6_add_video_clks(void __iomem *anab, void __iomem *cb)
+{
+	clks[pll5_post_div] = imx_clk_divider_table("pll5_post_div", "pll5_video", anab + 0xa0, 19, 2, post_div_table);
+	clks[pll5_video_div] = imx_clk_divider_table("pll5_video_div", "pll5_post_div", anab + 0x170, 30, 2, video_div_table);
+
+	clks[ipu1_sel]         = imx_clk_mux("ipu1_sel",         cb + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+	clks[ipu2_sel]         = imx_clk_mux("ipu2_sel",         cb + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+	clks[ldb_di0_sel]      = imx_clk_mux_p("ldb_di0_sel",      cb + 0x2c, 9,  3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+	clks[ldb_di1_sel]      = imx_clk_mux_p("ldb_di1_sel",      cb + 0x2c, 12, 3, ldb_di_sels,       ARRAY_SIZE(ldb_di_sels));
+	clks[ipu1_di0_pre_sel] = imx_clk_mux_p("ipu1_di0_pre_sel", cb + 0x34, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[ipu1_di1_pre_sel] = imx_clk_mux_p("ipu1_di1_pre_sel", cb + 0x34, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[ipu2_di0_pre_sel] = imx_clk_mux_p("ipu2_di0_pre_sel", cb + 0x38, 6,  3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[ipu2_di1_pre_sel] = imx_clk_mux_p("ipu2_di1_pre_sel", cb + 0x38, 15, 3, ipu_di_pre_sels,   ARRAY_SIZE(ipu_di_pre_sels));
+	clks[ipu1_di0_sel]     = imx_clk_mux_p("ipu1_di0_sel",     cb + 0x34, 0,  3, ipu1_di0_sels,     ARRAY_SIZE(ipu1_di0_sels));
+	clks[ipu1_di1_sel]     = imx_clk_mux_p("ipu1_di1_sel",     cb + 0x34, 9,  3, ipu1_di1_sels,     ARRAY_SIZE(ipu1_di1_sels));
+	clks[ipu2_di0_sel]     = imx_clk_mux_p("ipu2_di0_sel",     cb + 0x38, 0,  3, ipu2_di0_sels,     ARRAY_SIZE(ipu2_di0_sels));
+	clks[ipu2_di1_sel]     = imx_clk_mux_p("ipu2_di1_sel",     cb + 0x38, 9,  3, ipu2_di1_sels,     ARRAY_SIZE(ipu2_di1_sels));
+
+	clks[ipu1_podf]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          cb + 0x3c, 11, 3);
+	clks[ipu2_podf]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          cb + 0x3c, 16, 3);
+	clks[ldb_di0_div_3_5]  = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+	clks[ldb_di0_podf]     = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", cb + 0x20, 10, 1);
+	clks[ldb_di1_div_3_5]  = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+	clks[ldb_di1_podf]     = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", cb + 0x20, 11, 1);
+	clks[ipu1_di0_pre]     = imx_clk_divider("ipu1_di0_pre",     "ipu1_di0_pre_sel",  cb + 0x34, 3,  3);
+	clks[ipu1_di1_pre]     = imx_clk_divider("ipu1_di1_pre",     "ipu1_di1_pre_sel",  cb + 0x34, 12, 3);
+	clks[ipu2_di0_pre]     = imx_clk_divider("ipu2_di0_pre",     "ipu2_di0_pre_sel",  cb + 0x38, 3,  3);
+	clks[ipu2_di1_pre]     = imx_clk_divider("ipu2_di1_pre",     "ipu2_di1_pre_sel",  cb + 0x38, 12, 3);
+
+	clkdev_add_physbase(clks[ipu1_podf], MX6_IPU1_BASE_ADDR, "bus");
+	clkdev_add_physbase(clks[ipu1_di0_sel], MX6_IPU1_BASE_ADDR, "di0");
+	clkdev_add_physbase(clks[ipu1_di1_sel], MX6_IPU1_BASE_ADDR, "di1");
+	clkdev_add_physbase(clks[ipu2_podf], MX6_IPU2_BASE_ADDR, "bus");
+	clkdev_add_physbase(clks[ipu2_di0_sel], MX6_IPU2_BASE_ADDR, "di0");
+	clkdev_add_physbase(clks[ipu2_di1_sel], MX6_IPU2_BASE_ADDR, "di1");
+
+	clkdev_add_physbase(clks[ldb_di0_sel], 0x020e0008, "di0_pll");
+	clkdev_add_physbase(clks[ldb_di1_sel], 0x020e0008, "di1_pll");
+	clkdev_add_physbase(clks[ipu1_di0_sel], 0x020e0008, "di0_sel");
+	clkdev_add_physbase(clks[ipu1_di1_sel], 0x020e0008, "di1_sel");
+	clkdev_add_physbase(clks[ipu2_di0_sel], 0x020e0008, "di2_sel");
+	clkdev_add_physbase(clks[ipu2_di1_sel], 0x020e0008, "di3_sel");
+	clkdev_add_physbase(clks[ldb_di0], 0x020e0008, "di0");
+	clkdev_add_physbase(clks[ldb_di1], 0x020e0008, "di1");
+	clkdev_add_physbase(clks[ahb], 0x00120000, "iahb");
+	clkdev_add_physbase(clks[pll3_pfd1_540m], 0x00120000, "isfr");
+
+	clk_set_parent(clks[ipu1_di0_sel], clks[ipu1_di0_pre]);
+	clk_set_parent(clks[ipu1_di1_sel], clks[ipu1_di1_pre]);
+	clk_set_parent(clks[ipu2_di0_sel], clks[ipu2_di0_pre]);
+	clk_set_parent(clks[ipu2_di1_sel], clks[ipu2_di1_pre]);
+
+	clk_set_parent(clks[ipu1_di0_pre_sel], clks[pll5_video_div]);
+	clk_set_parent(clks[ipu1_di1_pre_sel], clks[pll5_video_div]);
+	clk_set_parent(clks[ipu2_di0_pre_sel], clks[pll5_video_div]);
+	clk_set_parent(clks[ipu2_di1_pre_sel], clks[pll5_video_div]);
+
+	if ((imx_silicon_revision() != IMX_CHIP_REV_1_0) ||
+	    cpu_is_mx6dl()) {
+		clk_set_parent(clks[ldb_di0_sel], clks[pll5_video_div]);
+		clk_set_parent(clks[ldb_di1_sel], clks[pll5_video_div]);
+	}
+
+}
+
 static int imx6_ccm_probe(struct device_d *dev)
 {
 	void __iomem *base, *anatop_base, *ccm_base;
@@ -281,7 +421,6 @@ static int imx6_ccm_probe(struct device_d *dev)
 	clks[arm]               = imx_clk_busy_divider("arm",               "pll1_sw",     base + 0x10, 0,   3,   base + 0x48, 16);
 	clks[ahb]               = imx_clk_busy_divider("ahb",               "periph",      base + 0x14, 10,  3,   base + 0x48, 1);
 
-
 	clkdev_add_physbase(clks[uart_serial_podf], MX6_UART1_BASE_ADDR, NULL);
 	clkdev_add_physbase(clks[uart_serial_podf], MX6_UART2_BASE_ADDR, NULL);
 	clkdev_add_physbase(clks[uart_serial_podf], MX6_UART3_BASE_ADDR, NULL);
@@ -310,10 +449,16 @@ static int imx6_ccm_probe(struct device_d *dev)
 	clkdev_add_physbase(clks[ipg_per], MX6_PWM3_BASE_ADDR, "per");
 	clkdev_add_physbase(clks[ipg_per], MX6_PWM4_BASE_ADDR, "per");
 
+	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+		imx6_add_video_clks(anatop_base, ccm_base);
+
 	writel(0xffffffff, ccm_base + CCGR0);
 	writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */
 	writel(0xffffffff, ccm_base + CCGR2);
-	writel(0x3fff0000, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */
+	if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3))
+		writel(0xffffffff, ccm_base + CCGR3); /* gate OpenVG */
+	else
+		writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */
 	writel(0xffffffff, ccm_base + CCGR4);
 	writel(0xffffffff, ccm_base + CCGR5);
 	writel(0xffff3fff, ccm_base + CCGR6); /* gate VPU */
diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h
index d83266b..32a02db 100644
--- a/arch/arm/mach-imx/clk.h
+++ b/arch/arm/mach-imx/clk.h
@@ -27,6 +27,12 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
 	return clk_mux(name, reg, shift, width, parents, num_parents, 0);
 }
 
+static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
+		u8 shift, u8 width, const char **parents, u8 num_parents)
+{
+	return clk_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT);
+}
+
 static inline struct clk *imx_clk_gate(const char *name, const char *parent,
 		void __iomem *reg, u8 shift)
 {
diff --git a/arch/arm/mach-imx/include/mach/imx6-regs.h b/arch/arm/mach-imx/include/mach/imx6-regs.h
index 833280a..facbe51 100644
--- a/arch/arm/mach-imx/include/mach/imx6-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx6-regs.h
@@ -26,6 +26,9 @@
 #define MX6_SPBA_BASE_ADDR              (MX6_ATZ1_BASE_ADDR + 0x3C000)
 #define MX6_VPU_BASE_ADDR               (MX6_ATZ1_BASE_ADDR + 0x40000)
 
+#define MX6_IPU1_BASE_ADDR		0x02400000
+#define MX6_IPU2_BASE_ADDR		0x02800000
+
 /* ATZ#1- On Platform */
 #define MX6_AIPS1_ON_BASE_ADDR          (MX6_ATZ1_BASE_ADDR + 0x7C000)
 
-- 
1.9.0


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

  parent reply	other threads:[~2014-03-14 14:33 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-14 14:32 i.MX IPUv3 support Sascha Hauer
2014-03-14 14:32 ` [PATCH 01/29] err.h: Add PTR_ERR_OR_ZERO from kernel Sascha Hauer
2014-03-14 14:32 ` [PATCH 02/29] ARM: i.MX6: Add initial variscite VAR-SOM-MX6 CPU support Sascha Hauer
2014-03-14 14:32 ` [PATCH 03/29] ARM: dts: i.MX6: Add IPU aliases Sascha Hauer
2014-03-14 14:32 ` [PATCH 04/29] ARM: dts: i.MX6: Add HDMI nodes Sascha Hauer
2014-03-14 14:32 ` [PATCH 05/29] ARM: dts: i.MX53: Fix IPU register size Sascha Hauer
2014-03-14 14:32 ` [PATCH 06/29] i2c: i.MX: move to earlier initcall Sascha Hauer
2014-03-14 14:32 ` [PATCH 07/29] i2c: implement of_find_i2c_adapter_by_node Sascha Hauer
2014-03-14 14:32 ` [PATCH 08/29] clk: implement clk_round_rate Sascha Hauer
2014-03-14 14:32 ` [PATCH 09/29] clk: clk-mux: pass clk flags from initializers Sascha Hauer
2014-03-14 14:32 ` [PATCH 10/29] clk: clk-gate: pass flags to initializers Sascha Hauer
2014-03-14 14:32 ` [PATCH 11/29] clk: clk-fixed-factor: " Sascha Hauer
2014-03-14 14:32 ` [PATCH 12/29] clk: clk-divider: " Sascha Hauer
2014-03-14 14:32 ` [PATCH 13/29] clk: introduce CLK_SET_RATE_PARENT flag Sascha Hauer
2014-03-14 16:06   ` Alexander Shiyan
2014-03-17  6:43     ` Sascha Hauer
2014-03-14 14:32 ` [PATCH 14/29] clk: clk-divider: sync with kernel code Sascha Hauer
2014-03-14 14:32 ` [PATCH 15/29] clk: let clk-divider handle the table based divider aswell Sascha Hauer
2014-03-14 14:32 ` [PATCH 16/29] clk: clk-fixed-factor: add set_rate/round_rate callbacks Sascha Hauer
2014-03-14 14:32 ` [PATCH 17/29] clk: Add parent round/set rate for mux and gate Sascha Hauer
2014-03-14 14:32 ` [PATCH 18/29] ARM: i.MX: introduce clk parent rate changes Sascha Hauer
2014-03-14 14:32 ` Sascha Hauer [this message]
2014-03-14 14:32 ` [PATCH 20/29] video: introduce struct display_timings Sascha Hauer
2014-03-14 14:32 ` [PATCH 21/29] video: rework mode_name parameter setting Sascha Hauer
2014-04-07 14:45   ` Alexander Shiyan
2014-04-08  6:39     ` Sascha Hauer
2014-03-14 14:32 ` [PATCH 22/29] video: Add display timing from devicetree helper Sascha Hauer
2014-03-14 14:32 ` [PATCH 23/29] video: Add edid support Sascha Hauer
2014-03-14 14:32 ` [PATCH 24/29] ARM i.MX6q: Mark VPU and IPU AXI transfers as cacheable, increase IPU priority Sascha Hauer
2014-03-14 14:32 ` [PATCH 25/29] video: Add kernel fourcc defines Sascha Hauer
2014-03-14 14:32 ` [PATCH 27/29] video: i.MX IPUv3: Add lvds bridge support Sascha Hauer
2014-03-14 14:32 ` [PATCH 28/29] video: i.MX IPUv3: Add hdmi support Sascha Hauer
2014-03-14 14:32 ` [PATCH 29/29] ARM: update imx_v7_defconfig Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1394807569-23620-20-git-send-email-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox