diff --git a/drivers/clk/keystone/clk-keystone-pll.c b/drivers/clk/keystone/clk-keystone-pll.c
new file mode 100644
index 0000000..0e1a1c4
--- /dev/null
+++ b/drivers/clk/keystone/clk-keystone-pll.c
@@ -0,0 +1,94 @@
+/*
+ * Main PLL clk driver for Keystone devices
+ *
+ * Copyright (C) 2012 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/platform_data/clk-keystone-pll.h>
+
+#include <mach/cputype.h>
+
+/**
+ * struct clk_pll - DaVinci Main pll clock
+ * @hw: clk_hw for the pll
+ * @pll_data: PLL driver specific data
+ */
+struct clk_pll {
+	struct clk_hw hw;
+	struct clk_keystone_pll_data *pll_data;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_pll, hw)
+
+static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct clk_pll *pll = to_clk_pll(hw);
+	struct clk_keystone_pll_data *pll_data = pll->pll_data;
+	unsigned long rate = parent_rate;
+	u32  pllm, plld, postdiv, val;
+
+	/* get bit0-5 of PLLM from PLLM PLL control register */
+	val = __raw_readl(pll_data->pllm);
+	pllm = (val & pll_data->pllm_lower_mask);
+
+	/* bit6-12 of PLLM is in Main PLL control register */
+	val = __raw_readl(pll_data->main_pll_ctl0);
+	pllm |= ((val & pll_data->pllm_upper_mask)
+			>> pll_data->pllm_upper_shift);
+	plld = (val & pll_data->plld_mask);
+	postdiv = pll_data->fixed_postdiv;
+
+	rate /= (plld + 1);
+	rate = (rate * (pllm + 1));
+	rate /= postdiv;
+
+	pr_notice("main_pll_clk rate is %ld, postdiv = %d, pllm = %d," \
+		"plld = %d\n", rate, postdiv, pllm, plld);
+	return rate;
+}
+
+static const struct clk_ops clk_pll_ops = {
+	.recalc_rate = clk_pllclk_recalc,
+};
+
+struct clk *clk_register_keystone_pll(struct device *dev, const char *name,
+			const char *parent_name,
+			struct clk_keystone_pll_data *pll_data)
+{
+	struct clk_init_data init;
+	struct clk_pll *pll;
+	struct clk *clk;
+
+	if (!pll_data)
+		return ERR_PTR(-ENODEV);
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &clk_pll_ops;
+	init.flags = 0;
+	init.parent_names = (parent_name ? &parent_name : NULL);
+	init.num_parents = (parent_name ? 1 : 0);
+
+	pll->pll_data	= pll_data;
+	pll->hw.init = &init;
+
+	clk = clk_register(NULL, &pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
diff --git a/include/linux/platform_data/clk-keystone-pll.h b/include/linux/platform_data/clk-keystone-pll.h
new file mode 100644
index 0000000..5d8f8a5
--- /dev/null
+++ b/include/linux/platform_data/clk-keystone-pll.h
@@ -0,0 +1,37 @@
+/*
+ * TI Keyston clk-pll driver platform data definitions
+ *
+ * Copyright (C) 2012 Texas Instruments.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __CLK_KEYSTONE_PLL_H
+#define __CLK_KEYSTONE_PLL_H
+
+struct clk_keystone_pll_data {
+	/* register holds lower bits of PLLM */
+	u32 phy_pllm;
+	/* holds upper bits of PLLM */
+	u32 phy_main_pll_ctl0;
+	/* mapped addresses. should be initialized by  */
+	void __iomem *pllm;
+	void __iomem *main_pll_ctl0;
+	u32 pllm_lower_mask;
+	u32 pllm_upper_mask;
+	u32 pllm_upper_shift;
+	u32 plld_mask;
+	/* use this value for postdiv */
+	u32 fixed_postdiv;
+};
+
+extern struct clk *clk_register_keystone_pll(struct device *dev,
+			const char *name, const char *parent_name,
+			struct clk_keystone_pll_data *pll_data);
+#endif /* CLK_KEYSTONE_PLL_H */
