[PATCH 2/3] ARM: tegra: Add clk_dev1/2 to tegra2_clocks.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Stephen Warren <swarren@xxxxxxxxxx>

These clocks are needed for the audio to work.

Signed-off-by: Stephen Warren <swarren@xxxxxxxxxx>
---
 arch/arm/mach-tegra/tegra2_clocks.c |  133 +++++++++++++++++++++++++++++++++++
 1 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 10e25fa..00a397d 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -28,6 +28,7 @@
 #include <asm/clkdev.h>
 
 #include <mach/iomap.h>
+#include <mach/pinmux.h>
 
 #include "clock.h"
 #include "fuse.h"
@@ -1007,6 +1008,98 @@ static struct clk_ops tegra_audio_sync_clk_ops = {
 	.set_parent = tegra2_audio_sync_clk_set_parent,
 };
 
+/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
+
+static void tegra2_cdev_clk_init(struct clk *c)
+{
+	int ret;
+	enum tegra_tristate tristate;
+	enum tegra_mux_func func;
+	const struct clk_mux_sel *sel;
+
+	c->state = ON;
+
+	if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+			PERIPH_CLK_TO_ENB_BIT(c)))
+		c->state = OFF;
+
+	ret = tegra_pinmux_get_tristate(c->reg, &tristate);
+	if (ret || tristate)
+		c->state = OFF;
+
+	ret = tegra_pinmux_get_func(c->reg, &func);
+	if (ret)
+		func = -1;
+
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->value == func) {
+			c->parent = sel->input;
+			break;
+		}
+	}
+
+	if (!c->parent)
+		c->state = OFF;
+}
+
+
+static int tegra2_cdev_clk_enable(struct clk *c)
+{
+	int ret;
+
+	ret = tegra_pinmux_set_tristate(c->reg, TEGRA_TRI_NORMAL);
+	if (ret) {
+		pr_err("Failed to drive %s\n", c->name);
+		return ret;
+	}
+
+	clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+		CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+
+	return 0;
+}
+
+static void tegra2_cdev_clk_disable(struct clk *c)
+{
+	int ret;
+
+	ret = tegra_pinmux_set_tristate(c->reg, TEGRA_TRI_TRISTATE);
+	if (ret)
+		pr_err("Failed to tristate %s\n", c->name);
+
+	clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+		CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+static int tegra2_cdev_clk_set_parent(struct clk *c, struct clk *p)
+{
+	const struct clk_mux_sel *sel;
+
+	for (sel = c->inputs; sel->input != NULL; sel++) {
+		if (sel->input == p) {
+			if (c->refcnt)
+				clk_enable_locked(p);
+
+			tegra_pinmux_set_func(c->reg, sel->value);
+
+			if (c->refcnt && c->parent)
+				clk_disable_locked(c->parent);
+
+			clk_reparent(c, p);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static struct clk_ops tegra_cdev_clk_ops = {
+	.init       = &tegra2_cdev_clk_init,
+	.enable     = &tegra2_cdev_clk_enable,
+	.disable    = &tegra2_cdev_clk_disable,
+	.set_parent = &tegra2_cdev_clk_set_parent,
+};
+
 /* Clock definitions */
 static struct clk tegra_clk_32k = {
 	.name = "clk_32k",
@@ -1408,6 +1501,44 @@ static struct clk tegra_clk_audio_2x = {
 	.parent    = &tegra_clk_audio,
 };
 
+static struct clk_mux_sel mux_cdev1[] = {
+	{ .input = &tegra_clk_m, .value = TEGRA_MUX_OSC},
+	{ .input = &tegra_pll_a_out0, .value = TEGRA_MUX_PLLA_OUT},
+	{ .input = &tegra_pll_m_out1, .value = TEGRA_MUX_PLLM_OUT1},
+	{ .input = &tegra_clk_audio, .value = TEGRA_MUX_AUDIO_SYNC},
+	{ 0, 0},
+};
+
+/* dap_mclk1, belongs to the cdev1 pingroup. */
+static struct clk tegra_clk_cdev1 = {
+	.name      = "cdev1",
+	.inputs    = mux_cdev1,
+	.ops       = &tegra_cdev_clk_ops,
+	.clk_num   = 94,
+	.reg       = TEGRA_PINGROUP_CDEV1,
+	.max_rate  = 73728000,
+};
+
+static struct clk_mux_sel mux_cdev2[] = {
+	{ .input = &tegra_clk_m, .value = TEGRA_MUX_OSC},
+#if 0 /* FIXME: not implemented */
+	{ .input = &tegra_clk_, .value = TEGRA_MUX_AHB_CLK},
+	{ .input = &tegra_clk_, .value = TEGRA_MUX_APB_CLK},
+#endif
+	{ .input = &tegra_pll_p_out4, .value = TEGRA_MUX_PLLP_OUT4},
+	{ 0, 0},
+};
+
+/* dap_mclk2, belongs to the cdev2 pingroup. */
+static struct clk tegra_clk_cdev2 = {
+	.name      = "cdev2",
+	.inputs    = mux_cdev2,
+	.ops       = &tegra_cdev_clk_ops,
+	.clk_num   = 93,
+	.reg       = TEGRA_PINGROUP_CDEV2,
+	.max_rate  = 73728000,
+};
+
 struct clk_lookup tegra_audio_clk_lookups[] = {
 	{ .con_id = "audio", .clk = &tegra_clk_audio },
 	{ .con_id = "audio_2x", .clk = &tegra_clk_audio_2x }
@@ -1737,6 +1868,8 @@ struct clk_lookup tegra_clk_lookups[] = {
 	CLK(NULL,	"pclk",		&tegra_clk_pclk),
 	CLK(NULL,	"clk_d",	&tegra_clk_d),
 	CLK(NULL,	"cpu",		&tegra_clk_virtual_cpu),
+	CLK(NULL,	"cdev1",	&tegra_clk_cdev1),
+	CLK(NULL,	"cdev2",	&tegra_clk_cdev2),
 };
 
 void __init tegra2_init_clocks(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux